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

Django模板中如何统计EventSite关联所有Concert的艺术家总数量?

问题原因

你的原有代码无法返回正确结果的核心原因是:site.event_concert.all 返回的是多个Concert对象组成的查询集,而artists是单个Concert实例的属性,不能直接在查询集上调用该属性,因此无法拿到统计值。

推荐实现:视图层提前统计

Django的模板设计原则不推荐在模板中执行复杂计算,将统计逻辑放到视图层处理性能更好,还可以通过ORM聚合查询避免N+1查询问题。

统计所有艺术家总数

视图层查询代码如下:

from django.db.models import Count

# 给每个EventSite对象 annotated 统计字段
event_sites = EventSite.objects.annotate(
    total_artists=Count('event_concert__artists', distinct=True)
)

参数distinct=True用于去重:如果同一个艺术家关联了该场地的多场演唱会,不会被重复统计;如果需要按参演人次统计,移除该参数即可。

同时统计英国艺术家数量

通过条件聚合即可实现:

from django.db.models import Count, Q

event_sites = EventSite.objects.annotate(
    total_artists=Count('event_concert__artists', distinct=True),
    british_artists=Count('event_concert__artists', filter=Q(event_concert__artists__is_british=True), distinct=True)
)

模板中直接调用annotate生成的属性即可:

{% for site in event_sites %}
{{ site.total_artists }},
<!-- 需要统计英国艺术家时替换为 {{ site.british_artists }} -->
{% endfor %}

备选方案:自定义模板过滤器

如果无法修改视图层代码,可以通过自定义模板过滤器实现统计逻辑:

  1. 首先在你的app目录下新建templatetags文件夹,添加__init__.py空文件和stats_filters.py文件,代码如下:
from django import template
from django.db.models import Count, Q, Sum

register = template.Library()

@register.filter
def get_total_artists(site):
    return site.event_concert.annotate(
        cnt=Count('artists', distinct=True)
    ).aggregate(total=Sum('cnt'))['total'] or 0

@register.filter
def get_british_artists(site):
    return site.event_concert.annotate(
        cnt=Count('artists', filter=Q(artists__is_british=True), distinct=True)
    ).aggregate(total=Sum('cnt'))['total'] or 0
  1. 模板中加载过滤器后调用:
{% load stats_filters %}

{% for site in event_sites %}
{{ site|get_total_artists }},
<!-- 英国艺术家统计调用 {{ site|get_british_artists }} -->
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:15:03