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
相关产品推荐
相关产品推荐

