添加过滤更改排序

时间:2014-02-18 08:33:54

标签: django-rest-framework

我有一个我想要添加过滤的ModelViewSet。我的简单模型看起来像

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

    class Meta:
        ordering = ['-date']

ModelViewSet(只读):

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

关于API的文章现在按照我预期的日期降序排序。现在我想允许过滤语言。我在settings.py中将过滤器后端设置为DjangoFilterBackend。我更新的ModelViewSet现在看起来像:

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

这会将排序更改为语言ASC。向查询集添加order_by('-date')不会更改任何内容。添加ordering = ('-date', )不会改变任何内容。 =>如何指定过滤和排序(或只是在允许过滤时使用默认排序)?

修改 当前的功能似乎来自默认情况下在Rest Framework中创建的AutoFilterSet: https://github.com/tomchristie/django-rest-framework/blob/822eb39599b248c68573c3095639a831ab6df99a/rest_framework/filters.py#L53 ... order_by=True在{django-filter get_ordering_field中处理https://github.com/alex/django-filter/blob/d88b98dd2b70551deb9c128b209fcf783b325acc/django_filters/filterset.py#L325

=>似乎我必须创建一个FilterSet类:

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

这看起来是否正确?似乎有点“多”/冗长以保留默认排序。

3 个答案:

答案 0 :(得分:3)

您可以在视图中添加OrderingFilter,指定FilterSet或更好:ordering = ['-date'],而不是实现自己的ordering = Article._meta.ordering,以便恢复丢失(默认)订购。这也允许您的用户使用ordering查询参数来覆盖结果的默认排序。

答案 1 :(得分:1)

请注意,此问题已在master ... https://github.com/tomchristie/django-rest-framework/pull/1836中得到解决,并将在2.4.3版本中发布。

答案 2 :(得分:0)

好问题。

可以将一个排序过滤器与Django-Filter结合使用,但我认为过滤后端应用重新排序功能是不对的。

在我的情况下,我必须缓存我的随机查询集,因此我不能再使用Django-Filter,即使我没有在页面的第一次异步调用中进行过滤。