Ordering based on SerializerField

40 views
Skip to first unread message

Antony Seedhouse

unread,
Feb 4, 2015, 6:48:39 AM2/4/15
to django-res...@googlegroups.com
As far as I can understand, if you have "renamed" fields in your Serializer class, ordering will only work by specifying the source field name, not the field name that is returned/shown in the frontend

e.g.

class MySerializer(serializers.ModelSerializer):
impressions = serializers.IntegerField(source='ad_impressions')

?ordering=impressions will not work, but ?ordering=ad_impressions will

Likewise ordering_fields = ('impressions', ) will error

Would it not be desired for this to work by default?


Antony Seedhouse

unread,
Feb 4, 2015, 8:22:54 AM2/4/15
to django-res...@googlegroups.com
Looking into https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/filters.py

To get the desired behaviour would require rewriting the field names from get_ordering to their respective source field, either

a) in get_ordering
b) after get_ordering and before remove_invalid_fields
c) in remove_invalid_fields

I learn towards b), which would mean adding something like rewrite_to_source_fields()

Would this be acceptable default behaviour, worthy of a pull request?

Tom Christie

unread,
Feb 4, 2015, 9:45:33 AM2/4/15
to django-res...@googlegroups.com
> Would it not be desired for this to work by default?

Probably, yes.

Antony Seedhouse

unread,
Feb 4, 2015, 10:36:28 AM2/4/15
to django-res...@googlegroups.com
Excellent :)

So far I have working method b) that involves building a mapping and using it to replace, which duplicates some of the code from remove_invalid_fields, so I am on the fence about whether it would be better/neater implemented directly in remove_invalid_fields; what do you think?

class SerializerFieldOrderingFilter(OrderingFilter):
def rewrite_to_source_fields(self, ordering, view):
# Rewrite Serializer fields to their source fields

serializer_class = getattr(view, 'serializer_class')
if serializer_class is None:
# Nothing to rewrite
return ordering

# get mapping of field_name to source
source_field_mapping = {
field_name: field.source or field_name for field_name, field in serializer_class().fields.items()
}

# rewrite to source field
for k, field in enumerate(ordering):
direction = '-' if field[0] == '-' else ''
if field.lstrip('-') in source_field_mapping.keys():
ordering[k] = direction + source_field_mapping[field.lstrip('-')]
return ordering

def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request)

if ordering:
# Rewrite Serializer fields as their source fields
ordering = self.rewrite_to_source_fields(ordering, view)
# Skip any incorrect parameters
ordering = self.remove_invalid_fields(queryset, ordering, view)

if not ordering:
# Use 'ordering' attribute by default
ordering = self.get_default_ordering(view)

if ordering:
return queryset.order_by(*ordering)

return queryset

Jonathan Liuti

unread,
Aug 11, 2016, 1:10:22 PM8/11/16
to Django REST framework
@tom where do you stand now regarding this issue? Seems pretty odd to offer model field names to the api user whereas they only see serializer field names.

Just wondering if it moved along somewhere else or if I should start implementing something custom on my side ;-)

Cheers,
John.

Tom Christie

unread,
Aug 12, 2016, 4:59:04 AM8/12/16
to Django REST framework
Not something that's come up on my radar at all anytime lately.
At the moment I don't have any particular opinion on if it's something that should be resolved in REST framework directly or if it should be dealt with in a third party package.

Jonathan Liuti

unread,
Aug 12, 2016, 6:02:27 AM8/12/16
to django-res...@googlegroups.com
I guess a third-party solution would make sense in regard of how it's done for the search filters. I just think that exposing the limitation of the OrderingFilter in the documentation would help in acknowledging the situation ;-)

Le ven. 12 août 2016 à 10:59, Tom Christie <christ...@gmail.com> a écrit :
Not something that's come up on my radar at all anytime lately.
At the moment I don't have any particular opinion on if it's something that should be resolved in REST framework directly or if it should be dealt with in a third party package.

--
You received this message because you are subscribed to a topic in the Google Groups "Django REST framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-rest-framework/t6YwVE-LnUo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-rest-fram...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages