{"id":9691,"library":"djangorestframework-filters","title":"Better filtering for Django REST Framework","description":"djangorestframework-filters (DRF-Filters) provides a more powerful and flexible filtering solution for Django REST Framework. It extends `django-filter` to integrate seamlessly with DRF, offering features like related field filtering, method-based filtering, and lookup customization. The current stable version is 0.11.1, with active development on a future 1.0.0 release, while 0.x continues to receive maintenance updates.","status":"active","version":"0.11.1","language":"en","source_language":"en","source_url":"https://github.com/philipn/django-rest-framework-filters","tags":["django","drf","filtering","rest-framework","api"],"install":[{"cmd":"pip install djangorestframework-filters","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core dependency for filtering logic; specific version required depends on `djangorestframework-filters` version.","package":"django-filter","optional":false},{"reason":"Integrates with Django REST Framework; requires DRF version >=3.0.0.","package":"djangorestframework","optional":false},{"reason":"Underlying web framework; requires Django version >=1.8.0.","package":"Django","optional":false}],"imports":[{"symbol":"RestFrameworkFilterBackend","correct":"from rest_framework_filters.backends import RestFrameworkFilterBackend"},{"symbol":"FilterSet","correct":"from rest_framework_filters import FilterSet"},{"symbol":"RelatedFilter","correct":"from rest_framework_filters import RelatedFilter"},{"symbol":"AllLookupsFilter","correct":"from rest_framework_filters import AllLookupsFilter"}],"quickstart":{"code":"import os\nfrom django.db import models\nfrom rest_framework import serializers, viewsets\nfrom rest_framework_filters import FilterSet, RelatedFilter\nfrom rest_framework_filters.backends import RestFrameworkFilterBackend\n\n# --- Minimal Django setup for demonstration (not for production) ---\n# from django.conf import settings\n# settings.configure(INSTALLED_APPS=['django.contrib.auth', 'django.contrib.contenttypes', 'rest_framework', 'rest_framework_filters'], DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}})\n# import django\n# django.setup()\n\n# --- 1. Define your Models ---\nclass Author(models.Model):\n    name = models.CharField(max_length=100)\n\n    def __str__(self):\n        return self.name\n\nclass Book(models.Model):\n    title = models.CharField(max_length=200)\n    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')\n    published_year = models.IntegerField()\n\n    def __str__(self):\n        return f'{self.title} by {self.author.name}'\n\n# --- 2. Define your FilterSet ---\nclass AuthorFilter(FilterSet):\n    class Meta:\n        model = Author\n        fields = ['name']\n\nclass BookFilter(FilterSet):\n    # Filter by author name (related field)\n    author = RelatedFilter(AuthorFilter, field_name='author', queryset=Author.objects.all())\n    \n    class Meta:\n        model = Book\n        fields = {\n            'title': ['iexact', 'icontains'],\n            'published_year': ['exact', 'gte', 'lte'],\n        }\n\n# --- 3. Define your Serializers ---\nclass AuthorSerializer(serializers.ModelSerializer):\n    class Meta:\n        model = Author\n        fields = '__all__'\n\nclass BookSerializer(serializers.ModelSerializer):\n    author = AuthorSerializer(read_only=True)\n    class Meta:\n        model = Book\n        fields = '__all__'\n\n# --- 4. Define your ViewSets with filter_backends ---\nclass BookViewSet(viewsets.ModelViewSet):\n    queryset = Book.objects.all()\n    serializer_class = BookSerializer\n    filter_backends = (RestFrameworkFilterBackend,)\n    filterset_class = BookFilter\n\nclass AuthorViewSet(viewsets.ModelViewSet):\n    queryset = Author.objects.all()\n    serializer_class = AuthorSerializer\n    filter_backends = (RestFrameworkFilterBackend,)\n    filterset_class = AuthorFilter\n\n# Example usage (assuming Django/DRF setup):\n# from rest_framework.test import APIClient\n# client = APIClient()\n# # Assuming you have data created, e.g., Author.objects.create(name='Jane Doe')\n# # response = client.get('/books/?author__name=Jane') # This would work if DRF endpoints were configured.\n# # print(response.data)\n","lang":"python","description":"This quickstart demonstrates how to define `FilterSet` classes for models, including `RelatedFilter` for filtering across relationships, and integrate them with Django REST Framework's `ModelViewSet` using the `RestFrameworkFilterBackend`."},"warnings":[{"fix":"Ensure `RelatedFilter` instances explicitly provide a `queryset` argument. E.g., `RelatedFilter(AuthorFilter, field_name='author', queryset=Author.objects.all())`.","message":"The `queryset` argument for `rest_framework_filters.RelatedFilter` became a required argument.","severity":"breaking","affected_versions":"0.10.0 and later"},{"fix":"Replace `MethodFilter(method='my_method')` with `Filter(method='my_method')` or directly define the method on your `FilterSet` and link via `method='my_method'` on a standard `Filter`.","message":"The `MethodFilter` class was deprecated. Its functionality was absorbed directly into the base `Filter` class.","severity":"deprecated","affected_versions":"0.9.0 and later"},{"fix":"Ensure your `django-filter` dependency matches the requirement of your `djangorestframework-filters` version. For `0.11.1`, ensure `django-filter>=1.0.0` is installed.","message":"Compatibility with `django-filter` underwent significant changes. Versions `0.9.x` were locked to `django-filter<1.0`, while versions `0.10.x` and later require `django-filter>=1.0.0`.","severity":"breaking","affected_versions":"0.9.x to 0.10.x transition"},{"fix":"Be mindful when using `AllLookupsFilter` alongside explicitly defined filters. Ensure field names do not clash, or carefully structure your `FilterSet` to manage the order of filter application.","message":"`AllLookupsFilter` can inadvertently override explicitly declared filters in a `FilterSet` if they share the same field name.","severity":"gotcha","affected_versions":"All versions, especially prior to 0.8.1 (where a fix addressed some cases)"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Add `queryset=YourRelatedModel.objects.all()` to your `RelatedFilter` instance. For example: `author = RelatedFilter(AuthorFilter, field_name='author', queryset=Author.objects.all())`.","cause":"Using `rest_framework_filters.RelatedFilter` in version 0.10.0 or later without providing the required `queryset` argument.","error":"TypeError: __init__() missing 1 required positional argument: 'queryset'"},{"fix":"Ensure your `ViewSet` includes `filter_backends = (RestFrameworkFilterBackend,)` and `filterset_class = YourFilterSetClass`.","cause":"The `filter_backends` attribute on your `ViewSet` is missing or incorrectly configured, or the `filterset_class` attribute is missing.","error":"AttributeError: 'RestFrameworkFilterBackend' object has no attribute 'get_filterset'"},{"fix":"Double-check that the `field_name` matches an actual field or relationship on your model, and that the `lookups` specified (e.g., `['exact', 'icontains']`) are valid for the field type.","cause":"Incorrect `field_name` or `lookups` specified in `RelatedFilter` or standard `Filter` definitions, or attempting to filter on a non-existent lookup for a field.","error":"django.core.exceptions.FieldError: Cannot resolve keyword 'related_field_name' into field."}]}