mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Avoided calling distinct on annotated fields in SearchFilter. (#6240)
Fixes #6094
This commit is contained in:
parent
2daf6f1341
commit
317174b163
|
@ -85,6 +85,9 @@ class SearchFilter(BaseFilterBackend):
|
|||
opts = queryset.model._meta
|
||||
if search_field[0] in self.lookup_prefixes:
|
||||
search_field = search_field[1:]
|
||||
# Annotated fields do not need to be distinct
|
||||
if isinstance(queryset, models.QuerySet) and search_field in queryset.query.annotations:
|
||||
return False
|
||||
parts = search_field.split(LOOKUP_SEP)
|
||||
for part in parts:
|
||||
field = opts.get_field(part)
|
||||
|
|
|
@ -5,6 +5,7 @@ import datetime
|
|||
import pytest
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import models
|
||||
from django.db.models.functions import Concat, Upper
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.six.moves import reload_module
|
||||
|
@ -329,6 +330,38 @@ class SearchFilterToManyTests(TestCase):
|
|||
assert len(response.data) == 1
|
||||
|
||||
|
||||
class SearchFilterAnnotatedSerializer(serializers.ModelSerializer):
|
||||
title_text = serializers.CharField()
|
||||
|
||||
class Meta:
|
||||
model = SearchFilterModel
|
||||
fields = ('title', 'text', 'title_text')
|
||||
|
||||
|
||||
class SearchFilterAnnotatedFieldTests(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
SearchFilterModel.objects.create(title='abc', text='def')
|
||||
SearchFilterModel.objects.create(title='ghi', text='jkl')
|
||||
|
||||
def test_search_in_annotated_field(self):
|
||||
class SearchListView(generics.ListAPIView):
|
||||
queryset = SearchFilterModel.objects.annotate(
|
||||
title_text=Upper(
|
||||
Concat(models.F('title'), models.F('text'))
|
||||
)
|
||||
).all()
|
||||
serializer_class = SearchFilterAnnotatedSerializer
|
||||
filter_backends = (filters.SearchFilter,)
|
||||
search_fields = ('title_text',)
|
||||
|
||||
view = SearchListView.as_view()
|
||||
request = factory.get('/', {'search': 'ABCDEF'})
|
||||
response = view(request)
|
||||
assert len(response.data) == 1
|
||||
assert response.data[0]['title_text'] == 'ABCDEF'
|
||||
|
||||
|
||||
class OrderingFilterModel(models.Model):
|
||||
title = models.CharField(max_length=20, verbose_name='verbose title')
|
||||
text = models.CharField(max_length=100)
|
||||
|
|
Loading…
Reference in New Issue
Block a user