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

Django中外键关联数据排除软删除项并统计数量的实现疑问

基础Django模型关系示例

现有代码结构

STATIONS_MODEL 字段

  • state
  • name
  • ROUTER:关联ROUTERS模型的外键

TICKET_MODEL 字段

  • STATIONS:关联station模型的外键,related_name为ticketforstation
  • softDelete:布尔类型

当前视图代码

context['stations'] = stations_model.objects.all()

当前模板代码

{% for station in stations %}
<div class="container">
 {{station.name}}
 <span>{{station.ticketforstation.all.count}}</span>
</div>
{% endfor %}

需求

现在要统计每个station关联的ticket中softDelete=False的记录数量,想实现类似这样的模板效果:

{% for station in stations %}
<div class="container">
 {{station.name}}
 <span>{{station.ticketforstation.(SOFTDELETED FALSE).count}}</span>
</div>
{% endfor %}

可行解决办法

1. 给模型加属性(简单直接)

在STATIONS_MODEL里定义一个属性,直接返回过滤后的有效ticket数量:

class STATIONS_MODEL(models.Model):
    # 原有字段...
    @property
    def active_ticket_count(self):
        return self.ticketforstation.filter(softDelete=False).count()

然后模板里直接用这个属性:

{% for station in stations %}
<div class="container">
 {{station.name}}
 <span>{{station.active_ticket_count}}</span>
</div>
{% endfor %}

2. 视图用annotate预计算(性能更优)

如果数据量较大,推荐在查询时就统计好,避免N+1数据库查询问题:

from django.db.models import Count, Q

context['stations'] = stations_model.objects.annotate(
    active_ticket_count=Count('ticketforstation', filter=Q(ticketforstation__softDelete=False))
)

模板同样直接调用active_ticket_count即可,和上面的模板代码一致。

3. 自定义模板过滤器(不推荐)

如果一定要在模板层面处理,可以写个自定义过滤器,但会增加模板复杂度:

  • 先在app下创建templatetags文件夹,新建custom_filters.py:
from django import template

register = template.Library()

@register.filter
def count_active_tickets(tickets):
    return tickets.filter(softDelete=False).count()
  • 模板开头加载过滤器:
{% load custom_filters %}
  • 然后在循环里使用:
{% for station in stations %}
<div class="container">
 {{station.name}}
 <span>{{station.ticketforstation|count_active_tickets}}</span>
</div>
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:01:11