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
相关产品推荐
相关产品推荐

