Commit d1cfec8d by Ryan P Kilby

Fix SearchFilter to-many behavior by ANDing cond's

parent f02b7f13
...@@ -140,12 +140,14 @@ class SearchFilter(BaseFilterBackend): ...@@ -140,12 +140,14 @@ class SearchFilter(BaseFilterBackend):
] ]
base = queryset base = queryset
conditions = []
for search_term in search_terms: for search_term in search_terms:
queries = [ queries = [
models.Q(**{orm_lookup: search_term}) models.Q(**{orm_lookup: search_term})
for orm_lookup in orm_lookups for orm_lookup in orm_lookups
] ]
queryset = queryset.filter(reduce(operator.or_, queries)) conditions.append(reduce(operator.or_, queries))
queryset = queryset.filter(reduce(operator.and_, conditions))
if self.must_call_distinct(queryset, search_fields): if self.must_call_distinct(queryset, search_fields):
# Filtering against a many-to-many field requires us to # Filtering against a many-to-many field requires us to
......
...@@ -5,6 +5,7 @@ import unittest ...@@ -5,6 +5,7 @@ import unittest
import warnings import warnings
from decimal import Decimal from decimal import Decimal
import django
import pytest import pytest
from django.conf.urls import url from django.conf.urls import url
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
...@@ -668,12 +669,15 @@ class SearchFilterToManyTests(TestCase): ...@@ -668,12 +669,15 @@ class SearchFilterToManyTests(TestCase):
b1 = Blog.objects.create(name='Blog 1') b1 = Blog.objects.create(name='Blog 1')
b2 = Blog.objects.create(name='Blog 2') b2 = Blog.objects.create(name='Blog 2')
# Multiple entries on Lennon published in 1979 - distinct should deduplicate
Entry.objects.create(blog=b1, headline='Something about Lennon', pub_date=datetime.date(1979, 1, 1)) Entry.objects.create(blog=b1, headline='Something about Lennon', pub_date=datetime.date(1979, 1, 1))
Entry.objects.create(blog=b1, headline='Another thing about Lennon', pub_date=datetime.date(1979, 6, 1)) Entry.objects.create(blog=b1, headline='Another thing about Lennon', pub_date=datetime.date(1979, 6, 1))
# Entry on Lennon *and* a separate entry in 1979 - should not match
Entry.objects.create(blog=b2, headline='Something unrelated', pub_date=datetime.date(1979, 1, 1)) Entry.objects.create(blog=b2, headline='Something unrelated', pub_date=datetime.date(1979, 1, 1))
Entry.objects.create(blog=b2, headline='Retrospective on Lennon', pub_date=datetime.date(1990, 6, 1)) Entry.objects.create(blog=b2, headline='Retrospective on Lennon', pub_date=datetime.date(1990, 6, 1))
@unittest.skipIf(django.VERSION < (1, 9), "Django 1.8 does not support transforms")
def test_multiple_filter_conditions(self): def test_multiple_filter_conditions(self):
class SearchListView(generics.ListAPIView): class SearchListView(generics.ListAPIView):
queryset = Blog.objects.all() queryset = Blog.objects.all()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment