Django REST Framework查询集未排序
我在模型中使用了 Meta
,并设置了 ordering = ['-published_date']
,意思是我希望按照发布时间的倒序排列。
现在在视图中:
class InvoiceViewSet(viewsets.ModelViewSet):
queryset = Invoice.objects.all()
serializer_class = InvoiceSerializer
filter_fields = ('table',)
还有序列化器:
class InvoiceSerializer(serializers.ModelSerializer):
items = ItemSerializer(many=True, allow_add_remove=True)
class Meta:
model = Invoice
fields = ('id', 'items', 'table', 'published_date')
但是这个排序没有起作用,它显示的是升序(ASC),而我需要的是降序(DESC),根本没有影响到顺序。
我哪里做错了呢?
5 个回答
0
如果你是从谷歌搜索“如何对django-filters的查询集进行排序”而来的话,欢迎你!
在django-filters中,有一个叫做OrderingFilter的东西,你可以用它来添加排序功能。
文档中的示例代码是这样的:
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']
这里的o是查询参数的名字。
所以如果你访问 www.domain.com/o=username
,它会返回按用户名排序的查询集。如果你想要按降序排序,只需访问 www.domain.com/o=-username
(注意在username前面有个-号)。
7
@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)
这个方法对我和其他人都有效,希望对你也有帮助。
30
在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')
32
如果你的模型确实有一个排序方式,那么在列表视图中默认会显示出来。我建议你重写一下 get_queryset()
方法,并在这里调试返回的结果,或者直接在查询集中添加排序。
举个例子:
queryset = Invoice.objects.all().order_by('-published_date')
你有没有可能配置了一个过滤器,导致排序被覆盖了?可以试试把所有过滤器都关掉,看看会发生什么。我注意到你设置了 filter_fields
属性,所以假设你的设置里有类似这样的内容……
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)
}
如果你把那部分注释掉,问题会解决吗?
24
解决办法是重写 filter_queryset
这个方法:
def filter_queryset(self, queryset):
queryset = super(InvoiceViewSet, self).filter_queryset(queryset)
return queryset.order_by('-published_date')