Django:计算与查询匹配的内容标签

Django: counting tags of contents that match a query

我需要在 Django 中构建一个查询,我觉得我在这里有点头疼,非常感谢任何帮助。 我有内容和标签,它们之间的关系为 table:

class Content(mixins.TracketEntity):
    publisher = models.ForeignKey(User)
    title = models.CharField(max_length=256, null=False, blank=False)
    data = jsonfield.JSONField()

class Tag(mixins.TracketEntity):
    publisher = models.ForeignKey(User)
    name = models.CharField(max_length=256, null=False, blank=False)

class ContentTag(models.Model):
    content = models.ForeignKey(Content)
    tag = models.ForeignKey(Tag)

现在,我可以按标题筛选内容,例如,像这样:

content_query = Content.objects.filter(title__icontains="matematica")

这将给出一个内容列表,比如:

并说这些内容有这些标签:

鉴于这种情况,我如何构建一个 Django 查询来 return 与 content_query 的内容关联的标签列表,以及每个标签的内容计数? 该查询的预期结果集为:

此外,这种查询将一直 运行 在数据库 (Postgres) 上。 我应该在数据库上添加哪些索引才能使其正常运行?

获取与标题包含 "matematica"

Content 个实例相关的所有标签
tags = Content.objects.filter(title__icontains="matematica").tags.all()

然后,统计标签。

result_dict = {}
for tag in tags:
    result_dict[tag.name] +=1

实际上,您可以通过聚合在单个查询中相当简单地执行此操作:

from django.db.models import Count
tags = (Tag.objects
        .filter(content__title__icontains='matematica')
        .values('name')
        .annotate(tag_count=Count('tag')))

为了完成这项工作,您需要在 Tag 上添加一个 ManyToMany 声明,该声明使用现有的 through-table、ContentTag:

content = models.ManyToManyField('Content', through='ContentTag')

因为 through-table 已经存在,这根本不会改变你的数据库。