amir boluri
amir boluri

Reputation: 57

django rest framework ordering non model field(serializer field)

i want to ordering on my fields like this:

class DealerBackOfficeViewSet(mixins.ListModelMixin,
                          mixins.RetrieveModelMixin,
                          mixins.CreateModelMixin,
                          mixins.UpdateModelMixin,
                          viewsets.GenericViewSet):
filter_backends = (filters.OrderingFilter,
                   )
ordering_fields = ('online',...)

this way of ordering work only on model's fields but online field defined in my serializer and while test in postman not work. i want to done it like this :

class CustomOrdering(filters.OrderingFilter):

def filter_queryset(self, request, queryset, view):
    params = request.query_params.get(self.ordering_param)
    if params == 'online':
        ...   my serializer codes
    return super(CustomOrdering, self).filter_queryset(request, queryset, view)

this problem is other fields ordering not work!! is there a way to solve it any way? if related docs help me please give me the link . thanks for your site

Upvotes: 1

Views: 2501

Answers (2)

amir boluri
amir boluri

Reputation: 57

after struggle in this challenge i undrestand that exist a way to some how indicate this fields as model field and not need to CustomOrdering and any extra codes! in my get_queryset function i change the code:

queryset = Dealer.objects.all()

to:

queryset = Dealer.objects.all().annotate(bids_count=Count('bid'), device_count=Count('device'))

note that this two fields in my serializer not in my model. in my serilizer change this two field from SerializerMethodField to IntegerField and clean the defs.

then in my api file add this:

filter_backends = (filters.OrderingFilter,)
ordering_fields = ('bids_count', 'device_count')

this my last serializer:

class DealerListSerializer(serializers.ModelSerializer):
    device_count = serializers.IntegerField()
    bids_count = serializers.IntegerField()

    class Meta:
        model = Dealer
        fields = ('id', 'last_name', 'first_name', 'username', 'person_trust', 'is_active',
                  'work_type', 'address', 'mobile', 'device_count', 'online', 'bids_count')

by this way my code is very clear and my CustomOrdering and all elif statements also clean!

Upvotes: 4

Saad Aleem
Saad Aleem

Reputation: 1745

It doesn't work because the fields defined in your serializer aren't part of the model. The ordering attribute only works for model fields. You'd probably have to introduce a work around like creating a dynamic field using annotations and then order using that field but this depends on whether or not your online field logic can be annotated.

Upvotes: 1

Related Questions