diff --git a/djangorestframework/mixins.py b/djangorestframework/mixins.py
index e2062326a..eb49d898f 100644
--- a/djangorestframework/mixins.py
+++ b/djangorestframework/mixins.py
@@ -6,6 +6,7 @@ classes that can be added to a `View`.
from django.contrib.auth.models import AnonymousUser
from django.core.paginator import Paginator
from django.db.models.fields.related import ForeignKey
+from django.db.models import Q
from django.http import HttpResponse
from django.utils.safestring import mark_safe
from urlobject import URLObject
@@ -463,12 +464,13 @@ class ModelMixin(object):
queryset = None
- def get_query_kwargs(self, *args, **kwargs):
+ def get_query_args(self, *args, **kwargs):
"""
Return a dict of kwargs that will be used to build the
model instance retrieval or to filter querysets.
"""
+ args = list(args)
kwargs = dict(kwargs)
# If the URLconf includes a .(?P?%s=
)
except for the exact
suffix which is the default:
The default statement between multiple fields is AND
, if the or__
prefix is used then the statement will be OR
(e.g. ?or__%s=
)
+.
exact
suffix which is the default:
return u"""%s\n\nFilter options%s:\n\n%s""" % (desc, filter_desc_req, filter_desc_fields_txt)
- def get_query_kwargs(self, *args, **kwargs):
+ def get_query_args(self, *args, **kwargs):
"""
- Return the `QuerySet`'s args according to the GET request's arguments.
+ Return the `QuerySet`'s args and kwargs according to the GET request's arguments.
"""
- kwargs = super(FilterMixin, self).get_query_kwargs(*args, **kwargs)
+ args, kwargs = super(FilterMixin, self).get_query_args(self, *args, **kwargs)
self._filter_triggered = False
+ q = None
- for k in self.request.GET:
+ for k, v in self.request.GET.items():
+
+ if k.startswith('or__'):
+ q_or = True
+ k = k[4:]
+ else: q_or = False
field = k.split('__')
if len(field) == 2: lookup = field[1]
else: lookup = 'exact'
field = field[0]
- value = self.request.GET[k]
- if field in self.filter_fields and lookup in self.filter_fields[field]:
+ if v and field in self.filter_fields and lookup in self.filter_fields[field]:
- value = self._filter_lookups[lookup](field, value)
- kwargs['%s__%s' % (field, lookup)] = value
+ v = self._filter_lookups[lookup](field, v)
+ if not q_or: kwargs['%s__%s' % (field, lookup)] = v
+ else:
+ q_this = Q(**{'%s__%s' % (field, lookup): v})
+ if q: q = q | q_this
+ else: q = q_this
self._filter_triggered = True
- return kwargs
+ if q: args.append(q)
+
+ return args, kwargs
def get(self, *args, **kwargs):
queryset = super(FilterMixin, self).get(*args, **kwargs)
- if self.filter_required and not self._filter_triggered: return self.resource.model.objects.none()
- return queryset
\ No newline at end of file
+ if self.filter_required and not self._filter_triggered:
+ return self.resource.model.objects.none()
+ return queryset