django rest框架queryset没有命令

Mir*_*lic 16 python django django-rest-framework

我使用模型 Meta ordering = ['-published_date']

现在看来:

class InvoiceViewSet(viewsets.ModelViewSet):
    queryset = Invoice.objects.all()
    serializer_class = InvoiceSerializer
    filter_fields = ('table',)
Run Code Online (Sandbox Code Playgroud)

和序列化器:

class InvoiceSerializer(serializers.ModelSerializer):
    items = ItemSerializer(many=True, allow_add_remove=True)

    class Meta:
        model = Invoice
        fields = ('id',  'items', 'table', 'published_date')
Run Code Online (Sandbox Code Playgroud)

但这种排序不起作用,它显示我订购ASC,我需要DESC,它根本不影响订单.

我究竟做错了什么?

Tom*_*tie 15

如果模型确实有一个排序它真的将反映在默认列表视图.我建议get_queryset()在那里覆盖和调试返回结果,或者明确地将顺序添加到查询集.

例如:

queryset = Invoice.objects.all().order_by('-published_date')
Run Code Online (Sandbox Code Playgroud)

想知道您是否可以配置一个覆盖排序的过滤器.值得测试如果关闭所有过滤器会发生什么.我看到你有filter_fields属性设置,所以假设你的设置中有这样的东西......

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
}
Run Code Online (Sandbox Code Playgroud)

如果你发表评论那会解决问题吗?


Mir*_*lic 12

解决方案是覆盖filter_queryset:

def filter_queryset(self, queryset):
    queryset = super(InvoiceViewSet, self).filter_queryset(queryset)
    return queryset.order_by('-published_date')
Run Code Online (Sandbox Code Playgroud)

  • 对于一个简单的功能来说,这是一个很大的开销。我想知道这在过去的 4.5 年里是否发生了变化? (3认同)

小智 11

对于 Django REST 框架,您可以使用OrderingFilter

from django_filters import DjangoFilterBackend
from rest_framework import viewsets, filters


class InvoiceViewSet(viewsets.ModelViewSet):
    queryset = Invoice.objects.all()
    serializer_class = InvoiceSerializer

    filter_backends = (DjangoFilterBackend, filters.OrderingFilter)

    # Explicitly specify which fields the API may be ordered against
    ordering_fields = ('items', 'table', 'published_date')

    # This will be used as the default ordering
    ordering = ('-published_date')
Run Code Online (Sandbox Code Playgroud)

  • 对于那些在 DRF 中手动通过查询参数进行排序的人来说,这在几分钟内解决了几个小时的头痛问题。谢谢! (2认同)

Edg*_*arT 6

@Mirza Delic的答案有效但不保持从request.QUERY_PARAMS开始的顺序.

class YOUR_VIEW_SET(viewsets.ModelViewSet):
    #your code here
    ordering_filter = OrderingFilter()

    def filter_queryset(self, queryset):
        queryset = super(YOUR_VIEW_SET, self).filter_queryset(queryset)
        return self.ordering_filter.filter_queryset(self.request, queryset, self)
Run Code Online (Sandbox Code Playgroud)

这对我和我希望的其他人都有用.