aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
authorTom Christie2013-05-07 12:25:41 +0100
committerTom Christie2013-05-07 12:25:41 +0100
commitd71a5533f9a8787652244dfb16af37fb7d9059fb (patch)
tree9d7d4ad3e15a55d8a5e67c0888d91fd2f88edc61 /rest_framework
parentb70c9cc107743b45edc50c4b4e5e6a7d5a856f01 (diff)
downloaddjango-rest-framework-d71a5533f9a8787652244dfb16af37fb7d9059fb.tar.bz2
allow_empty -> pending deprecation in preference of overridden get_queryset.
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/filters.py29
-rw-r--r--rest_framework/generics.py12
2 files changed, 38 insertions, 3 deletions
diff --git a/rest_framework/filters.py b/rest_framework/filters.py
index 5e1cdbac..571704dc 100644
--- a/rest_framework/filters.py
+++ b/rest_framework/filters.py
@@ -3,7 +3,10 @@ Provides generic filtering backends that can be used to filter the results
returned by list views.
"""
from __future__ import unicode_literals
+
+from django.db import models
from rest_framework.compat import django_filters
+import operator
FilterSet = django_filters and django_filters.FilterSet or None
@@ -62,3 +65,29 @@ class DjangoFilterBackend(BaseFilterBackend):
return filter_class(request.QUERY_PARAMS, queryset=queryset).qs
return queryset
+
+
+class SearchFilter(BaseFilterBackend):
+ def construct_search(self, field_name):
+ if field_name.startswith('^'):
+ return "%s__istartswith" % field_name[1:]
+ elif field_name.startswith('='):
+ return "%s__iexact" % field_name[1:]
+ elif field_name.startswith('@'):
+ return "%s__search" % field_name[1:]
+ else:
+ return "%s__icontains" % field_name
+
+ def filter_queryset(self, request, queryset, view):
+ search_fields = getattr(view, 'search_fields', None)
+
+ if not search_fields:
+ return None
+
+ orm_lookups = [self.construct_search(str(search_field))
+ for search_field in self.search_fields]
+ for bit in self.query.split():
+ or_queries = [models.Q(**{orm_lookup: bit})
+ for orm_lookup in orm_lookups]
+ queryset = queryset.filter(reduce(operator.or_, or_queries))
+ return queryset
diff --git a/rest_framework/generics.py b/rest_framework/generics.py
index 62129dcc..2bb23a89 100644
--- a/rest_framework/generics.py
+++ b/rest_framework/generics.py
@@ -42,9 +42,6 @@ class GenericAPIView(views.APIView):
# The filter backend class to use for queryset filtering
filter_backend = api_settings.FILTER_BACKEND
- # Determines if the view will return 200 or 404 responses for empty lists.
- allow_empty = True
-
# The following attributes may be subject to change,
# and should be considered private API.
model_serializer_class = api_settings.DEFAULT_MODEL_SERIALIZER_CLASS
@@ -56,6 +53,7 @@ class GenericAPIView(views.APIView):
pk_url_kwarg = 'pk'
slug_url_kwarg = 'slug'
slug_field = 'slug'
+ allow_empty = True
def get_serializer_context(self):
"""
@@ -111,6 +109,14 @@ class GenericAPIView(views.APIView):
if not page_size:
return None
+ if not self.allow_empty:
+ warnings.warn(
+ 'The `allow_empty` parameter is due to be deprecated. '
+ 'To use `allow_empty=False` style behavior, You should override '
+ '`get_queryset()` and explicitly raise a 404 on empty querysets.',
+ PendingDeprecationWarning, stacklevel=2
+ )
+
paginator = self.paginator_class(queryset, page_size,
allow_empty_first_page=self.allow_empty)
page_kwarg = self.kwargs.get(self.page_kwarg)