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

Django ORM如何统计模型对象间非去重多对多关联总数

问题描述

假设定义了如下Django模型:

class Tag(Model):
    name = CharField()

class Book(Model):
    title = CharField()
    tags = ManyToManyField(Tag)

现有3本图书,每本关联3个标签,不同图书允许关联重复标签,不影响统计逻辑,示例数据如下:

Book 1 (Tags = "tag1", "tag2", "tag3")
Book 2 (Tags = "tag1", "tag4", "tag5")
Book 3 (Tags = "tag4", "tag5", "tag6")

需求是编写Django ORM查询语句,统计所有非去重的标签关联总次数,预期结果为9。

实现方法

Django的多对多字段会自动生成一张中间关联表,表中每一行记录就对应一次「图书-标签」的绑定关系,哪怕多个图书绑定同一个标签,也会生成独立的记录,不存在去重逻辑,直接统计这张表的总记录数就能得到想要的结果,写法最简单性能也最高:

total_relation_count = Book.tags.through.objects.count()

执行上述语句返回的结果就是9,完全匹配需求。

避坑说明

  • 不要用Tag.objects.count():这个语句统计的是去重后的标签总数量,按照示例数据返回结果是6,不符合要求。
  • 不推荐用聚合嵌套写法:比如Book.objects.annotate(t_num=Count('tags')).aggregate(total=Sum('t_num'))虽然计算结果也对,但会先按图书分组统计每本书的标签数,再做求和,数据量大的时候性能远差于直接统计中间表。
  • 调试时可以直接遍历中间表记录核对关联关系:
    for rel in Book.tags.through.objects.all():
        print(f"关联关系:图书ID {rel.book_id} <-> 标签ID {rel.tag_id}")
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:51:19