Lädt...


🔧 Comprehensive Guide to Filtering in Django REST Framework (DRF) with a Real-World Example


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

When building APIs, you often deal with large datasets, and filtering is a must to allow users to retrieve only the data they need. Filtering in APIs allows users to search and narrow down results based on specific criteria. Thankfully, Django REST Framework (DRF) makes this process straightforward with the help of Django-filter, a powerful package that allows for flexible and efficient filtering.

In this blog post, we’ll walk through building an API with filtering using a real-world example. We’ll use Django-filter to handle common filtering operations, including searching by name, filtering by tech stack, and using date ranges. By the end, you’ll have a solid understanding of implementing filtering in your APIs.

Table of Contents:

  1. The Problem We're Solving
  2. Setting Up the Project
  • Project Initialization
  • Installing Django-filter
  • Building the Models
  • Creating the API Views
  • Implementing Filtering with Django-filter
  • Testing the API
  • Conclusion
  • The Problem We're Solving

    Imagine you’re building a project management application where users can create and manage projects. Users need to:

    • Search for projects by name.
    • Filter projects by tech stack (e.g., Python, JavaScript).
    • Retrieve projects created within a specific date range.

    We’ll build an API to handle these requests efficiently using Django REST Framework and Django-filter.

    Setting Up the Project

    Project Initialization

    First, let's set up a Django project. Open your terminal and run the following commands:

    python shell commands
    Now, add the project's app to INSTALLED_APPS in project_management/settings.py:

    INSTALLED_APPS = [
        # Django default apps
        'rest_framework',
        'django_filters',  # Adding django-filter
        'projects',  # Our project app
    ]
    
    

    Configure DRF to use DjangoFilterBackend by adding this to settings.py:

    REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 10,  # Limit results per page to 10
    }
    
    

    DjangoFilterBackend is the bridge between DRF and Django-filters, allowing you to use the powerful filtering capabilities of Django-filters in your DRF views.

    Adding DjangoFilterBacked will allow all views that use the default filter backend to support filtering using the DjangoFilterBackend.

    Building the Models

    In the real world, project management systems often have models like Project and Category. Let’s create a Project model where each project has a name, description, tech stack, and creation date.

    In projects/models.py, add the following code:

    from django.db import models
    
    class Project(models.Model):
        name = models.CharField(max_length=255)
        description = models.TextField()
        tech_stack = models.CharField(max_length=255)  # e.g., Python, JavaScript
        created_at = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return self.name
    
    

    We now have a basic model to store project information. Each project has a name, description, tech_stack (which lists technologies like Python, Django, etc.), and a created_at field to track when the project was added.

    Next, we’ll create a migration and apply it:

    python manage.py makemigrations
    python manage.py migrate
    
    

    We now have the basic Project model set up in our database.
    Let’s add some sample data into our Project model. You can create this data directly in your Django shell or by using the Django admin.

    Step 1: Open Django Shell

    python manage.py shell
    
    

    Step 2: Add Sample Data

    from projects.models import Project
    from datetime import datetime
    
    # Sample data
    Project.objects.create(name="Alpha Project", description="A project management tool.", tech_stack="Python, Django", created_at=datetime(2023, 1, 15))
    Project.objects.create(name="Beta System", description="An inventory system.", tech_stack="Java, Spring Boot", created_at=datetime(2023, 2, 10))
    Project.objects.create(name="Gamma Build", description="A continuous integration tool.", tech_stack="Python, Docker", created_at=datetime(2023, 3, 20))
    Project.objects.create(name="Delta Tracker", description="A time tracking tool.", tech_stack="Node.js, Express", created_at=datetime(2023, 4, 25))
    
    

    Now we have four projects in our database, each with different tech stacks and creation dates. These will serve as our test data for the filtering functionality.

    Creating the API Views

    Let’s define an API that allows users to:

    • Retrieve a list of all projects.
    • Search for projects by name.
    • Filter projects by tech stack or creation date.

    First, let's create a serializer in projects/serializers.py to convert Project instances into JSON:

    from rest_framework import serializers
    from .models import Project
    
    class ProjectSerializer(serializers.ModelSerializer):
        class Meta:
            model = Project
            fields = ['id', 'name', 'description', 'tech_stack', 'created_at']
    
    

    Now, let’s define an API view to list all projects. Open projects/views.py and create a simple view using Django REST Framework’s ListAPIView:

    from rest_framework import generics
    from .models import Project
    from .serializers import ProjectSerializer
    
    class ProjectListView(generics.ListAPIView):
        queryset = Project.objects.all()
        serializer_class = ProjectSerializer
    
    

    Next, Create and add the route for this view in projects/urls.py:

    from django.urls import path
    from .views import ProjectListView
    
    urlpatterns = [
        path('projects/', ProjectListView.as_view(), name='project-list'),
    ]
    

    Include this in your main urls.py file:

    from django.urls import path, include
    
    urlpatterns = [
        path('api/', include('projects.urls')),
    ]
    
    

    Now, you can run the server python manage.py runserver and visit /api/projects/ to see the list of all projects we created.

    ListAPIView

    But there’s no filtering yet, so let’s fix that next!

    Implementing Filtering with Django-filter

    To add filtering, we’ll use Django-filter’s FilterSet to allow users to search by project name, and tech stack, and filter by creation date.

    Step 1: Define a FilterSet

    Create a filter class in projects/filters.py:

    import django_filters
    from .models import Project
    
    
    class ProjectFilter(django_filters.FilterSet):
        name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
        tech_stack = django_filters.CharFilter(field_name='tech_stack', lookup_expr='icontains')
    
    
        class Meta:
            model = Project
            fields = ['name', 'tech_stack', 'created_at']
    
    
    

    This defines a custom filter class called ProjectFilter. The filter class extends django_filters.FilterSet, a base class provided by django-filter to define filters for a particular model.

    In this class:

    Two filters are defined: name and tech_stack.

    name = django_filters.CharFilter(...): This defines a filter for the name field.

    • field_name='name': This tells the filter to target the name field in the Project model.

    • lookup_expr='icontains': This sets the lookup expression to icontains, this will filter for case-insensitive, partial matches on the name field. For example, searching for "alpha" will match project names like "Alpha Project", "alpha beta" or "ALPHA".

    tech_stack = django_filters.CharFilter(...): This filter targets the tech_stack field and applies the same logic:

    • field_name='tech_stack': This tells the filter to target the tech_stack field in the Project model.

    • lookup_expr='icontains': This allows for case-insensitive, partial matching on the tech_stack field. Searching for "Python" will match any tech stack that includes "Python," " Django," or "React, Python."

    The Meta class provides additional configuration for the ProjectFilter.

    • model = Project: This tells the filter that it is based on the Project model, meaning the filtering logic will be applied to the Project table in the database.

    • fields = ['name', 'tech_stack', 'created_at']: This defines the fields in the Project model that can be filtered. Learn more about django-filter here

    Step 2: Add Filtering to the View

    Now, update your ProjectListView to use filtering:

    from django_filters.rest_framework import DjangoFilterBackend
    from .filters import ProjectFilter
    
    class ProjectListView(generics.ListAPIView):
        queryset = Project.objects.all()
        serializer_class = ProjectSerializer
        filter_backends = [DjangoFilterBackend]  # Enable filtering
        filterset_class = ProjectFilter  # Use our custom filter
    
    

    Testing the API

    Let’s test the filtering functionality using some of the examples we created above.

    Example 1: Searching by Project Name

    To search for projects with "alpha" in their name, you can use this URL:

    /api/projects/?name=alpha
    
    

    filter by name

    Example 2: Filtering by Tech Stack

    You can filter projects based on the technologies used in their tech stack. For example:

    /api/projects/?tech_stack=Python
    
    

    filter by tech-stack

    Conclusion
    In this blog post, we’ve seen how to build an API with filtering in Django REST Framework using Django-filter. We covered how to:

    • Set up a project and create a basic API.
    • Implement search and filtering by name, and tech stack using FilterSet.
    • Test the filtering functionality with sample data.

    By leveraging Django-filter you can offer efficient filtering options in your APIs with minimal effort. This helps reduce the load on your database, ensures faster queries, and provides a more tailored user experience.

    Link for Further reading:

    Django-filter official documentation
    Djangorestframework

    Link to example code: Filtering-in-Django-REST-Framework

    ...

    🔧 Basic CRUD API using Django and Django REST Framework (DRF) || Simple API for managing a list of books.


    📈 61.24 Punkte
    🔧 Programmierung

    🔧 Django REST Framework (DRF) - ModelViewSets


    📈 51.2 Punkte
    🔧 Programmierung

    🔧 Django REST Framework (DRF) CheatSheet


    📈 51.2 Punkte
    🔧 Programmierung

    🔧 Django REST Framework (DRF) CheatSheet


    📈 51.2 Punkte
    🔧 Programmierung

    🔧 Implementing Search Functionality in Django Rest Framework (DRF)


    📈 51.2 Punkte
    🔧 Programmierung

    🕵️ CVE-2018-25045 | Django REST Framework up to 3.9.0 DRF Browsable API cross site scripting


    📈 51.2 Punkte
    🕵️ Sicherheitslücken

    🔧 Master API Development with Django REST Framework – Learn Django REST Framework for Free!


    📈 50.84 Punkte
    🔧 Programmierung

    🔧 Crafting Modern Web APIs with Django and Django REST Framework: A Comprehensive Guide


    📈 48.16 Punkte
    🔧 Programmierung

    🔧 Complete Guide to the Django Services and Repositories Design Pattern with the Django REST Framework


    📈 40.18 Punkte
    🔧 Programmierung

    🔧 Using React CKEditor 5 with Django(DRF)


    📈 35.82 Punkte
    🔧 Programmierung

    🔧 Instance version control in DRF with Django Reversion


    📈 35.82 Punkte
    🔧 Programmierung

    🔧 Django vs Django REST Framework: ¿Cuál es la diferencia? 🤔


    📈 35.46 Punkte
    🔧 Programmierung

    🔧 RESTful API in Django [Django Rest Framework]


    📈 35.46 Punkte
    🔧 Programmierung

    🔧 Login with OTP Authentication in Django and Django REST Framework


    📈 35.46 Punkte
    🔧 Programmierung

    🔧 Build a Multivendor E-commerce Website using Django, React & Django Rest Framework


    📈 35.46 Punkte
    🔧 Programmierung

    🔧 Understanding REST APIs - A Comprehensive Guide with Practical Example


    📈 33.61 Punkte
    🔧 Programmierung

    🔧 Understanding One2Many Relationships in Odoo: A Comprehensive Guide with Real Use Case Example


    📈 31.27 Punkte
    🔧 Programmierung

    🔧 A Beginner’s Guide to Django Web Framework: Django from Novice to Expert


    📈 31.01 Punkte
    🔧 Programmierung

    🔧 Announcing my new Django package: django-admin-export! #packaging #python #django


    📈 30.13 Punkte
    🔧 Programmierung

    🔧 FullStack Next.js & Django Authentication: Django REST, TypeScript, JWT, Wretch & Djoser


    📈 29.26 Punkte
    🔧 Programmierung

    📰 What is URL filtering? Web filtering explained


    📈 28.49 Punkte
    📰 IT Security Nachrichten

    🔧 Типизация в drf-spectacular


    📈 25.78 Punkte
    🔧 Programmierung

    🔧 Views no DRF: Funções ou classes? A escolha simples


    📈 25.78 Punkte
    🔧 Programmierung

    🔧 Consideraciones en los serializadores del DRF


    📈 25.78 Punkte
    🔧 Programmierung

    📰 DRF Luftrettung: So kündigen Sie Ihre Mitgliedschaft


    📈 25.78 Punkte
    🖥️ Betriebssysteme

    🔧 How to Name Endpoints in a REST API: Complete Guide with Best Practices and Practical Example


    📈 25.63 Punkte
    🔧 Programmierung

    🔧 Build a Blog API With JWT Authentication Using Django Rest Framework


    📈 25.42 Punkte
    🔧 Programmierung

    🔧 Why I Think Django Rest Framework is the Best for Developing Robust APIs


    📈 25.42 Punkte
    🔧 Programmierung

    🔧 Build a Blog API With JWT Authentication Using Django Rest Framework


    📈 25.42 Punkte
    🔧 Programmierung

    🔧 The Best Way to Implement API Versioning in Django REST Framework (Agile) 💎


    📈 25.42 Punkte
    🔧 Programmierung

    🔧 Use Django REST Framework to Create Web APIs


    📈 25.42 Punkte
    🔧 Programmierung

    🔧 Django Rest Framework


    📈 25.42 Punkte
    🔧 Programmierung

    matomo