diff options
| author | Tom Christie | 2013-05-07 12:25:41 +0100 |
|---|---|---|
| committer | Tom Christie | 2013-05-07 12:25:41 +0100 |
| commit | d71a5533f9a8787652244dfb16af37fb7d9059fb (patch) | |
| tree | 9d7d4ad3e15a55d8a5e67c0888d91fd2f88edc61 /rest_framework | |
| parent | b70c9cc107743b45edc50c4b4e5e6a7d5a856f01 (diff) | |
| download | django-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.py | 29 | ||||
| -rw-r--r-- | rest_framework/generics.py | 12 |
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) |
