mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-29 04:54:00 +03:00
Fix dotted source ordering (#5533)
* replaced '.' for '__' in dotted ordering sources * Add test for non-dotted source.
This commit is contained in:
parent
7261ae653a
commit
1f693c331e
|
@ -199,7 +199,7 @@ class OrderingFilter(BaseFilterBackend):
|
|||
raise ImproperlyConfigured(msg % self.__class__.__name__)
|
||||
|
||||
return [
|
||||
(field.source or field_name, field.label)
|
||||
(field.source.replace('.', '__') or field_name, field.label)
|
||||
for field_name, field in serializer_class(context=context).fields.items()
|
||||
if not getattr(field, 'write_only', False) and not field.source == '*'
|
||||
]
|
||||
|
|
|
@ -312,6 +312,7 @@ class OrderingFilterModel(models.Model):
|
|||
|
||||
class OrderingFilterRelatedModel(models.Model):
|
||||
related_object = models.ForeignKey(OrderingFilterModel, related_name="relateds", on_delete=models.CASCADE)
|
||||
index = models.SmallIntegerField(help_text="A non-related field to test with", default=0)
|
||||
|
||||
|
||||
class OrderingFilterSerializer(serializers.ModelSerializer):
|
||||
|
@ -320,6 +321,19 @@ class OrderingFilterSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
|
||||
class OrderingDottedRelatedSerializer(serializers.ModelSerializer):
|
||||
related_text = serializers.CharField(source='related_object.text')
|
||||
related_title = serializers.CharField(source='related_object.title')
|
||||
|
||||
class Meta:
|
||||
model = OrderingFilterRelatedModel
|
||||
fields = (
|
||||
'related_text',
|
||||
'related_title',
|
||||
'index',
|
||||
)
|
||||
|
||||
|
||||
class DjangoFilterOrderingModel(models.Model):
|
||||
date = models.DateField()
|
||||
text = models.CharField(max_length=10)
|
||||
|
@ -484,6 +498,36 @@ class OrderingFilterTests(TestCase):
|
|||
{'id': 2, 'title': 'yxw', 'text': 'bcd'},
|
||||
]
|
||||
|
||||
def test_ordering_by_dotted_source(self):
|
||||
|
||||
for index, obj in enumerate(OrderingFilterModel.objects.all()):
|
||||
OrderingFilterRelatedModel.objects.create(
|
||||
related_object=obj,
|
||||
index=index
|
||||
)
|
||||
|
||||
class OrderingListView(generics.ListAPIView):
|
||||
serializer_class = OrderingDottedRelatedSerializer
|
||||
filter_backends = (filters.OrderingFilter,)
|
||||
queryset = OrderingFilterRelatedModel.objects.all()
|
||||
|
||||
view = OrderingListView.as_view()
|
||||
request = factory.get('/', {'ordering': 'related_object__text'})
|
||||
response = view(request)
|
||||
assert response.data == [
|
||||
{'related_title': 'zyx', 'related_text': 'abc', 'index': 0},
|
||||
{'related_title': 'yxw', 'related_text': 'bcd', 'index': 1},
|
||||
{'related_title': 'xwv', 'related_text': 'cde', 'index': 2},
|
||||
]
|
||||
|
||||
request = factory.get('/', {'ordering': '-index'})
|
||||
response = view(request)
|
||||
assert response.data == [
|
||||
{'related_title': 'xwv', 'related_text': 'cde', 'index': 2},
|
||||
{'related_title': 'yxw', 'related_text': 'bcd', 'index': 1},
|
||||
{'related_title': 'zyx', 'related_text': 'abc', 'index': 0},
|
||||
]
|
||||
|
||||
def test_ordering_with_nonstandard_ordering_param(self):
|
||||
with override_settings(REST_FRAMEWORK={'ORDERING_PARAM': 'order'}):
|
||||
reload_module(filters)
|
||||
|
|
Loading…
Reference in New Issue
Block a user