7

I have a ModelViewSet that I want to add filtering to. My simple model looks like

class Article(models.Model):
    date = = models.DateField()
    language = models.CharField(max_length=10)

    class Meta:
        ordering = ['-date']

And the ModelViewSet (read only):

class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

Articles on the API are now ordered by date descending as I would expect. Now I wich to allow filtering on language. I've set the filter backend to DjangoFilterBackend in settings.py. My updated ModelViewSet now looks like:

class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    filter_fields = ['language']

This changes the ordering to language ASC. Adding order_by('-date') to queryset does not change anything. Adding ordering = ('-date', ) does not change anything. => How do I specify both filtering and ordering (or simply use default ordering while allowing filtering)?

EDIT: Current functionality seems to come from AutoFilterSet created in Rest Framework by default: https://github.com/tomchristie/django-rest-framework/blob/822eb39599b248c68573c3095639a831ab6df99a/rest_framework/filters.py#L53 ... where order_by=True and the handing of this in django-filter get_ordering_field here: https://github.com/alex/django-filter/blob/d88b98dd2b70551deb9c128b209fcf783b325acc/django_filters/filterset.py#L325

=> Seems I have to create a FilterSet class:

class LanguageFilter(django_filters.FilterSet):
    class Meta:
        model = Article
        fields = ['language']
        order_by = model()._meta.ordering

class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    filter_class = LanguageFilter

Does this look correct? Seems a bit "much"/verbose to retain default ordering.

2
  • Ordering is database/query specific and potentially arbitrary unless you explicitly set an order. Any user-facing list should have an order-by. Commented Feb 18, 2014 at 8:53
  • 1
    Ordering already set on Article.Meta - which is respected until starting to filter Commented Feb 18, 2014 at 8:54

3 Answers 3

4

Rather than implementing your own FilterSet, you can instead just add an OrderingFilter, specifying an ordering = ['-date'] or better: ordering = Article._meta.ordering on your view, to restore the lost (default) ordering. This would also allow your users to use an ordering query parameter to override your default ordering of results.

Sign up to request clarification or add additional context in comments.

Comments

1

Note that this issue has been resolved in master... https://github.com/tomchristie/django-rest-framework/pull/1836 and is due to be released in version 2.4.3.

Comments

0

Good question.

Is ok to apply an ordering filter in conjuction with a Django-Filter but I think is not right that a Filter Backend applies a reorder function.

In my case I have to cache my random queryset and so i can't use Django-Filter anymore, even if I'm not filtering at the page's first asyncronous call.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.