Django模板中如何统计外键关联模型的记录数量
你当前模板中{{ registro.count }}无法正常取值,是因为遍历出的registro是单个RegAcceso模型实例,本身不存在count属性,需要通过两表的外键关联获取对应Registro记录的数量,以下是三种可行实现方案,优先推荐性能最优的第一种。
方案1:视图层聚合查询(最优,无性能问题)
通过Django ORM的annotate+Count聚合,在查询RegAcceso列表时一次性关联计算出每条记录对应的Registro数量,不会产生额外的N+1查询问题,适合所有场景。
- 首先在视图文件顶部导入Count聚合类:
from django.db.models import Count
- 修改视图中查询
query_historia的代码:
# 原代码:query_historia = RegAcceso.objects.filter(reg_user=request.user) # 修改为: query_historia = RegAcceso.objects.filter(reg_user=request.user).annotate( registros_count=Count('registro') )
注:由于你在
Registro模型的外键id_reg中未指定related_name,Django默认反向关联名为小写模型名registro,如果后续给外键添加了related_name='xxx',此处Count参数要替换为你设置的xxx。
- 修改模板中取值的代码,把原来的
{{ registro.count }}替换为{{ registro.registros_count }}即可,示例:
<a href="{% url 'historico' registro.id %}"> {{ registro.fecha|date:"d/m/Y h:i a" }} (关联Registro记录数:{{ registro.registros_count }}) </a>
方案2:模型层添加属性方法
如果多个模板/视图都需要用到这个计数,可以在RegAcceso模型中添加计算属性,复用逻辑。
- 在
RegAcceso模型类中添加如下代码:
class RegAcceso(models.Model): reg_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) fecha = models.DateTimeField(auto_now_add=True) # 新增属性方法 @property def registros_count(self): return self.registro_set.count() def __str__(self): return f'{self.id} - {self.reg_user} - {self.fecha.strftime("%d/%m/%Y")}' class Meta: ordering = ['-fecha']
- 模板中直接使用
{{ registro.registros_count }}即可取值,不需要修改视图代码。
注意:该方案存在N+1查询问题——如果列表中有N条RegAcceso记录,会额外执行N次COUNT查询,仅适合数据量较小的场景。
方案3:模板直接调用反向关系(临时快速实现)
不需要修改模型和视图,直接在模板中通过Django默认的反向关联管理器调用count方法即可:
把模板中的{{ registro.count }}替换为:
{{ registro.registro_set.count }}
注意:该方案和方案2一样存在N+1查询性能问题,仅适合临时调试、数据量极小的场景使用。
内容的提问来源于stack exchange,提问作者Eugenio
相关产品推荐
相关产品推荐

