简体   繁体   English

django 休息框架查询集不订购

[英]django rest framework queryset doesn't order

i use model with Meta ordering = ['-published_date']我使用带有Meta ordering = ['-published_date']

Now in view:现在看来:

class InvoiceViewSet(viewsets.ModelViewSet):
    queryset = Invoice.objects.all()
    serializer_class = InvoiceSerializer
    filter_fields = ('table',)

And serializer:和序列化器:

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

    class Meta:
        model = Invoice
        fields = ('id',  'items', 'table', 'published_date')

But this ordering doesn't work, it shows me ordering ASC, and i need DESC, it doesn't affect order at all.但是这个排序不起作用,它显示我在订购 ASC,而我需要 DESC,它根本不影响订单。

What am i doing wrong?我究竟做错了什么?

If your model does have an ordering it really will be reflected in the list view by default. 如果模型确实有一个排序它真的将反映在默认列表视图。 I'd suggest overriding get_queryset() and debugging the return result there, or else explicitly adding the ordering to the queryset. 我建议覆盖get_queryset()并在那里调试返回结果,否则显式地将顺序添加到查询集。

For example: 例如:

queryset = Invoice.objects.all().order_by('-published_date')

Wondering if it's possible you've configured a filter that's overriding the ordering. 想知道您是否可以配置一个覆盖排序的过滤器。 Worth testing what happens if you turn all filters off. 值得测试如果关闭所有过滤器会发生什么。 I see you have the filter_fields attribute set, so assuming you've got something like this in your settings... 我看到你设置了filter_fields属性,所以假设你的设置中有这样的东西......

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
}

If you comment that out does that fix things? 如果你发表评论那会解决问题吗?

Solution is to override filter_queryset : 解决方案是覆盖filter_queryset

def filter_queryset(self, queryset):
    queryset = super(InvoiceViewSet, self).filter_queryset(queryset)
    return queryset.order_by('-published_date')

@Mirza Delic answer works but does not keep the ordering comming from request.QUERY_PARAMS. @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)

This works for me and for other people I hope. 这对我和我希望的其他人都有用。

For Django REST Framework you can use OrderingFilter . 对于Django REST Framework,您可以使用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')

If anyone's coming here from google for 'How to order django-filters queryset'.如果有人从谷歌来到这里是为了“如何订购 django-filters 查询集”。

There's OrderingFilter in django-filters, which you can use to add the order_by functionality. django-filters 中有OrderingFilter ,您可以使用它来添加 order_by 功能。 The example code from the docs looks like this :文档中的示例代码如下所示:

class UserFilter(FilterSet):
account = CharFilter(field_name='username')
status = NumberFilter(field_name='status')

o = OrderingFilter(
    # tuple-mapping retains order
    fields=(
        ('username', 'account'),
        ('first_name', 'first_name'),
        ('last_name', 'last_name'),
    ),

    # labels do not need to retain order
    field_labels={
        'username': 'User account',
    }
)

class Meta:
    model = User
    fields = ['first_name', 'last_name']

Where o is the name of the query param.其中 o 是查询参数的名称。 So if you hit www.domain.com/o=username .因此,如果您点击www.domain.com/o=username It will return the queryset ordered by username.它将返回按用户名排序的查询集。 If you want to order_by in descending order.如果要按降序 order_by。 Just do www.domain.com/o=-username (notice the - before username).只需执行www.domain.com/o=-username (注意 - 在用户名之前)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM