You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Rest Framework排序功能失效,疑似与get_queryset有关如何解决?

DRF排序功能失效问题解决方案

根因分析

  • 你重写了ListAPIView的list方法,跳过了DRF默认的过滤器执行逻辑:原生list方法会调用self.filter_queryset()对查询集做过滤、排序处理,你直接取get_queryset()返回的原始查询集,完全没有走OrderingFilter的排序流程,导致排序不生效。
  • 你在ordering_fields中添加了cpc、cpm两个序列化后动态计算的非数据库字段,排序过滤器是作用在数据库查询阶段的,数据库中不存在这两个字段,按这两个字段排序也会失效。

修复步骤

  1. 先修复基础排序逻辑:在list方法中先调用filter_queryset处理查询集,把原有list方法的第一行修改为:
queryset = self.filter_queryset(self.get_queryset())

修改后即可支持date、views、clicks、cost这几个数据库原生字段的排序功能。

  1. 如果需要支持cpc、cpm字段的排序,建议把计算逻辑移到数据库查询层,通过annotate生成计算字段,修改后的完整视图代码如下:
from django.db.models import F, ExpressionWrapper, FloatField

class ShowStats(ListAPIView):
    serializer_class = StatsSerializer

    filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
    ordering_fields = ('date', 'views', 'clicks', 'cost', 'cpc', 'cpm')
    ordering = ('views',)

    def get_queryset(self):
        return Stats.objects.filter(
            date__range=[self.kwargs['from'], self.kwargs['to']]
        ).annotate(
            cpc=ExpressionWrapper(F('cost')/F('clicks'), output_field=FloatField()),
            cpm=ExpressionWrapper(F('cost')/F('views')*1000, output_field=FloatField())
        )

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response(data=serializer.data)

该方案直接在数据库层面完成字段计算和排序,性能远高于序列化后在Python层做排序,适合各类数据量场景。

内容的提问来源于stack exchange,提问作者gornichnyx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 19:39:02