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

在DRF中如何排序列表,使有关联Blog的用户优先、再按用户ID排序

解决方案

你可以通过Django ORM的注解功能给用户增加「是否存在关联Blog」的标识,再基于该标识做自定义排序即可,具体修改如下:

步骤1:导入依赖模块

首先在视图文件头部导入需要的ORM工具:

from django.db.models import Exists, OuterRef

步骤2:重写视图的get_queryset方法

修改原有UserAPIView,自定义查询逻辑和排序规则:

class UserAPIView(ListAPIView):
    serializer_class = UserSerializer

    def get_queryset(self):
        # 子查询判断当前用户是否有关联的Blog实例
        has_blog = Exists(Blog.objects.filter(user=OuterRef('pk')))
        # 给查询集新增has_blog注解字段,先按是否有Blog降序,再按用户ID升序排序
        return User.objects.annotate(
            has_blog=has_blog
        ).order_by('-has_blog', 'id')

实现说明

  • Exists是Django专门用于存在性检查的子查询工具,性能远高于统计关联数量的方案,只需判断有没有关联数据,不需要计算具体数值
  • 注解生成的has_blog为布尔类型,True代表用户有绑定的Blog,False代表没有
  • 排序规则中-has_blog代表按布尔值倒序,布尔值在数据库中会以1(True)、0(False)存储,所以有Blog的用户会全部排在最前面
  • 后续的id升序规则会对没有Blog的用户生效,按用户ID从小到大排列

兼容低版本Django方案

如果你使用的Django版本低于3.0(不支持Exists语法),可以用条件注解实现相同效果:

from django.db.models import Case, When, BooleanField

class UserAPIView(ListAPIView):
    serializer_class = UserSerializer

    def get_queryset(self):
        return User.objects.annotate(
            has_blog=Case(
                When(blog__isnull=False, then=True),
                default=False,
                output_field=BooleanField()
            )
        ).order_by('-has_blog', 'id')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:36:04