aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2012-11-08 21:46:53 +0000
committerTom Christie2012-11-08 21:46:53 +0000
commitbc6f2a170306fbc1cba3a4e504a908ebc72d54b7 (patch)
tree8722b675ea4c5ce29822476f304e1389c870a4af
parentc78b34d5017a05220bcd623946b4f52cc2d119cd (diff)
downloaddjango-rest-framework-bc6f2a170306fbc1cba3a4e504a908ebc72d54b7.tar.bz2
Make default FILTER_BACKEND = None
-rw-r--r--docs/api-guide/filtering.md14
-rw-r--r--rest_framework/filters.py21
-rw-r--r--rest_framework/runtests/settings.py1
-rw-r--r--rest_framework/settings.py9
-rw-r--r--rest_framework/tests/filterset.py5
-rw-r--r--rest_framework/tests/pagination.py3
6 files changed, 38 insertions, 15 deletions
diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md
index ea1e7d23..ca901b03 100644
--- a/docs/api-guide/filtering.md
+++ b/docs/api-guide/filtering.md
@@ -82,17 +82,19 @@ We can override `.get_queryset()` to deal with URLs such as `http://example.com/
As well as being able to override the default queryset, REST framework also includes support for generic filtering backends that allow you to easily construct complex filters that can be specified by the client using query parameters.
-REST framework supports pluggable backends to implement filtering, and includes a default implementation which uses the [django-filter] package.
+REST framework supports pluggable backends to implement filtering, and provides an implementation which uses the [django-filter] package.
To use REST framework's default filtering backend, first install `django-filter`.
pip install -e git+https://github.com/alex/django-filter.git#egg=django-filter
-**Note**: The currently supported version of `django-filter` is the `master` branch. A PyPI release is expected to be coming soon.
+You must also set the filter backend to `DjangoFilterBackend` in your settings:
-## Specifying filter fields
+ REST_FRAMEWORK = {
+ 'FILTER_BACKEND': 'rest_framework.filters.DjangoFilterBackend'
+ }
-**TODO**: Document setting `.filter_fields` on the view.
+**Note**: The currently supported version of `django-filter` is the `master` branch. A PyPI release is expected to be coming soon.
## Specifying a FilterSet
@@ -100,6 +102,10 @@ To use REST framework's default filtering backend, first install `django-filter`
**TODO**: Note support for `lookup_type`, double underscore relationship spanning, and ordering.
+## Specifying filter fields
+
+**TODO**: Document setting `.filter_fields` on the view.
+
**TODO**: Note that overiding `get_queryset()` can be used together with generic filtering
---
diff --git a/rest_framework/filters.py b/rest_framework/filters.py
index b972e82a..14902a69 100644
--- a/rest_framework/filters.py
+++ b/rest_framework/filters.py
@@ -17,6 +17,10 @@ class DjangoFilterBackend(BaseFilterBackend):
"""
A filter backend that uses django-filter.
"""
+ default_filter_set = django_filters.FilterSet
+
+ def __init__(self):
+ assert django_filters, 'Using DjangoFilterBackend, but django-filter is not installed'
def get_filter_class(self, view):
"""
@@ -24,20 +28,21 @@ class DjangoFilterBackend(BaseFilterBackend):
"""
filter_class = getattr(view, 'filter_class', None)
filter_fields = getattr(view, 'filter_fields', None)
- filter_model = getattr(view, 'model', None)
-
- if filter_class or filter_fields:
- assert django_filters, 'django-filter is not installed'
+ view_model = getattr(view, 'model', None)
if filter_class:
- assert issubclass(filter_class.Meta.model, filter_model), \
- '%s is not a subclass of %s' % (filter_class.Meta.model, filter_model)
+ filter_model = filter_class.Meta.model
+
+ assert issubclass(filter_model, view_model), \
+ 'FilterSet model %s does not match view model %s' % \
+ (filter_model, view_model)
+
return filter_class
if filter_fields:
- class AutoFilterSet(django_filters.FilterSet):
+ class AutoFilterSet(self.default_filter_set):
class Meta:
- model = filter_model
+ model = view_model
fields = filter_fields
return AutoFilterSet
diff --git a/rest_framework/runtests/settings.py b/rest_framework/runtests/settings.py
index b48f85e4..dd5d9dc3 100644
--- a/rest_framework/runtests/settings.py
+++ b/rest_framework/runtests/settings.py
@@ -107,6 +107,7 @@ import django
if django.VERSION < (1, 3):
INSTALLED_APPS += ('staticfiles',)
+
# If we're running on the Jenkins server we want to archive the coverage reports as XML.
import os
if os.environ.get('HUDSON_URL', None):
diff --git a/rest_framework/settings.py b/rest_framework/settings.py
index da647658..906a7cf6 100644
--- a/rest_framework/settings.py
+++ b/rest_framework/settings.py
@@ -55,7 +55,7 @@ DEFAULTS = {
'anon': None,
},
'PAGINATE_BY': None,
- 'FILTER_BACKEND': 'rest_framework.filters.DjangoFilterBackend',
+ 'FILTER_BACKEND': None,
'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',
'UNAUTHENTICATED_TOKEN': None,
@@ -144,8 +144,15 @@ class APISettings(object):
if val and attr in self.import_strings:
val = perform_import(val, attr)
+ self.validate_setting(attr, val)
+
# Cache the result
setattr(self, attr, val)
return val
+ def validate_setting(self, attr, val):
+ if attr == 'FILTER_BACKEND' and val is not None:
+ # Make sure we can initilize the class
+ val()
+
api_settings = APISettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS)
diff --git a/rest_framework/tests/filterset.py b/rest_framework/tests/filterset.py
index 6cdea32f..af2e6c2e 100644
--- a/rest_framework/tests/filterset.py
+++ b/rest_framework/tests/filterset.py
@@ -3,7 +3,7 @@ from decimal import Decimal
from django.test import TestCase
from django.test.client import RequestFactory
from django.utils import unittest
-from rest_framework import generics, status
+from rest_framework import generics, status, filters
from rest_framework.compat import django_filters
from rest_framework.tests.models import FilterableItem, BasicModel
@@ -15,6 +15,7 @@ if django_filters:
class FilterFieldsRootView(generics.ListCreateAPIView):
model = FilterableItem
filter_fields = ['decimal', 'date']
+ filter_backend = filters.DjangoFilterBackend
# These class are used to test a filter class.
class SeveralFieldsFilter(django_filters.FilterSet):
@@ -29,6 +30,7 @@ if django_filters:
class FilterClassRootView(generics.ListCreateAPIView):
model = FilterableItem
filter_class = SeveralFieldsFilter
+ filter_backend = filters.DjangoFilterBackend
# These classes are used to test a misconfigured filter class.
class MisconfiguredFilter(django_filters.FilterSet):
@@ -41,6 +43,7 @@ if django_filters:
class IncorrectlyConfiguredRootView(generics.ListCreateAPIView):
model = FilterableItem
filter_class = MisconfiguredFilter
+ filter_backend = filters.DjangoFilterBackend
class IntegrationTestFiltering(TestCase):
diff --git a/rest_framework/tests/pagination.py b/rest_framework/tests/pagination.py
index 7f8cd524..713a7255 100644
--- a/rest_framework/tests/pagination.py
+++ b/rest_framework/tests/pagination.py
@@ -4,7 +4,7 @@ from django.core.paginator import Paginator
from django.test import TestCase
from django.test.client import RequestFactory
from django.utils import unittest
-from rest_framework import generics, status, pagination
+from rest_framework import generics, status, pagination, filters
from rest_framework.compat import django_filters
from rest_framework.tests.models import BasicModel, FilterableItem
@@ -31,6 +31,7 @@ if django_filters:
model = FilterableItem
paginate_by = 10
filter_class = DecimalFilter
+ filter_backend = filters.DjangoFilterBackend
class IntegrationTestPagination(TestCase):