I’m using django rest framework and I would like to order with a custom method.
So, when I call this url for example : http://127.0.0.1:8000/api/sets/?ordering=partMissing
It’s possible to call a custom method because I would like to order with the number of part missing by snippet. I made count the sum of number of part in the many to many field.
I have very simple POC, that should allow you to implement more sophisticated solution.
from rest_framework import viewsets from ordering_test.models import Test from ordering_test.ordering import MyCustomOrdering from ordering_test.serializers import TestSerializer class TestViewSet(viewsets.ModelViewSet): queryset = Test.objects.all() serializer_class = TestSerializer filter_backends = (MyCustomOrdering,)
from rest_framework.filters import OrderingFilter class MyCustomOrdering(OrderingFilter): allowed_custom_filters = ['testMethod'] def get_ordering(self, request, queryset, view): """ Ordering is set by a comma delimited ?ordering=... query parameter. The `ordering` query parameter can be overridden by setting the `ordering_param` value on the OrderingFilter or by specifying an `ORDERING_PARAM` value in the API settings. """ params = request.query_params.get(self.ordering_param) if params: fields = [param.strip() for param in params.split(',')] # care with that - this will alow only custom ordering! ordering = [f for f in fields if f in self.allowed_custom_filters] if ordering: return ordering # No ordering was included, or all the ordering fields were invalid return self.get_default_ordering(view) def filter_queryset(self, request, queryset, view): ordering = self.get_ordering(request, queryset, view) if ordering: # implement a custom ordering here ordering = ['-id'] if ordering: return queryset.order_by(*ordering) return queryset
serializers.py are straightforward, but I will still include them here:
from django.db import models class Test(models.Model): test = models.CharField(max_length=120) test1 = models.CharField(max_length=120)
from rest_framework import serializers from ordering_test.models import Test class TestSerializer(serializers.ModelSerializer): class Meta: model = Test fields = ('test', 'test1')
Answered By – opalczynski