mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-07 13:54:47 +03:00
Restore meta information for each search field.
The meta information stored in opts needs to be restored for each search field. Otherwise it references the wrong model when an attribute of a related model comes before an attribute of the original model in search fields. This doesn't apply to m2m relations since must_call_distinct returns True in that case.
This commit is contained in:
parent
0f61c9ec29
commit
c5a2a13040
|
@ -174,8 +174,8 @@ class SearchFilter(BaseFilterBackend):
|
|||
"""
|
||||
Return True if 'distinct()' should be used to query the given lookups.
|
||||
"""
|
||||
opts = queryset.model._meta
|
||||
for search_field in search_fields:
|
||||
opts = queryset.model._meta
|
||||
if search_field[0] in self.lookup_prefixes:
|
||||
search_field = search_field[1:]
|
||||
parts = search_field.split(LOOKUP_SEP)
|
||||
|
|
|
@ -454,6 +454,47 @@ class AttributeModel(models.Model):
|
|||
label = models.CharField(max_length=32)
|
||||
|
||||
|
||||
class SearchFilterModelFk(models.Model):
|
||||
title = models.CharField(max_length=20)
|
||||
attribute = models.ForeignKey(AttributeModel)
|
||||
|
||||
|
||||
class SearchFilterFkSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SearchFilterModelFk
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class SearchFilterFkTests(TestCase):
|
||||
|
||||
def test_must_call_distinct(self):
|
||||
filter_ = filters.SearchFilter()
|
||||
prefixes = [''] + list(filter_.lookup_prefixes)
|
||||
for prefix in prefixes:
|
||||
self.assertFalse(
|
||||
filter_.must_call_distinct(
|
||||
SearchFilterModelFk._meta, ["%stitle" % prefix]
|
||||
)
|
||||
)
|
||||
self.assertFalse(
|
||||
filter_.must_call_distinct(
|
||||
SearchFilterModelFk._meta, ["%stitle" % prefix, "%sattribute__label" % prefix]
|
||||
)
|
||||
)
|
||||
|
||||
def test_must_call_distinct_restores_meta_for_each_field(self):
|
||||
# In this test case the attribute of the fk model comes first in the
|
||||
# list of search fields.
|
||||
filter_ = filters.SearchFilter()
|
||||
prefixes = [''] + list(filter_.lookup_prefixes)
|
||||
for prefix in prefixes:
|
||||
self.assertFalse(
|
||||
filter_.must_call_distinct(
|
||||
SearchFilterModelFk._meta, ["%sattribute__label" % prefix, "%stitle" % prefix]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class SearchFilterModelM2M(models.Model):
|
||||
title = models.CharField(max_length=20)
|
||||
text = models.CharField(max_length=100)
|
||||
|
|
Loading…
Reference in New Issue
Block a user