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

Django中如何合并并排序两个模型字段的计数结果

解决方案

你可以通过Django的Subquery和Coalesce实现单次查询获取人员的发送+接收信件总次数,并按总次数排序。这种方法完全通过数据库查询完成,避免了在Python中合并数据的繁琐操作,效率更高。

完整代码实现:

from django.db.models import Count, F, Subquery, OuterRef, Coalesce
from .models import Person, Letter

# 子查询:计算每个人员的发送信件数
sent_subquery = Letter.objects.filter(
    sender=OuterRef('pk')
).values('sender').annotate(
    sent_count=Count('pk')
).values('sent_count')

# 子查询:计算每个人员的接收信件数
received_subquery = Letter.objects.filter(
    recipient=OuterRef('pk')
).values('recipient').annotate(
    received_count=Count('pk')
).values('received_count')

# 注解总次数并排序Person查询集
people_with_total_letters = Person.objects.annotate(
    sent_count=Coalesce(Subquery(sent_subquery), 0),
    received_count=Coalesce(Subquery(received_subquery), 0)
).annotate(
    total_count=F('sent_count') + F('received_count')
).order_by('-total_count')

关键细节说明:

  • Subquery:针对每个Person实例单独执行计数子查询,避免了多表连接导致的重复计数问题。
  • Coalesce:将无信件记录人员的计数从None转为0,保证求和逻辑正常运行。
  • order_by('-total_count'):按总信件数从高到低排序,改为order_by('total_count')可实现升序排列。

最终得到的people_with_total_letters查询集包含每个Person的sent_count、received_count和total_count字段,可直接传入模板使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:30:07