如何在Django模板中获取ManyToManyField关联对象的count统计值
解决方案
问题原因说明
你之前的写法存在两个核心问题:
get()是QuerySet用于获取单个匹配对象的方法,匹配结果数量不为1时会抛出异常,完全不能用于统计数量,统计数量要使用count()方法- Django模板语法不支持直接调用带参数的方法,因此你写的
{{tutorobj.students.get(type=ONLINE)}}这类写法无法生效,业务统计逻辑需要放在视图或者模型方法中处理
方案1:在视图中直接统计(简单易理解)
修改views.py中的tutor视图,提前计算好两类课程的数量传入模板即可:
def tutor(request, pk): tutorObj = Tutor.objects.get(id=pk) # 统计该老师的线下课总数 class_lesson_count = Lesson.objects.filter(headed_by=tutorObj, student__type='CLASS').count() # 统计该老师的线上课总数 online_lesson_count = Lesson.objects.filter(headed_by=tutorObj, student__type='ONLINE').count() # 如果你需要的是不同类型的学生数量,用下面两句替代上面两句即可 # class_student_count = tutorObj.students.filter(type='CLASS').count() # online_student_count = tutorObj.students.filter(type='ONLINE').count() context = { "tutorobj": tutorObj, "class_lesson_count": class_lesson_count, "online_lesson_count": online_lesson_count } return render(request, 'tutor.html', context)
在tutor.html模板中直接渲染数值:
<div> <p>线下课总数量:{{ class_lesson_count }}</p> <p>线上课总数量:{{ online_lesson_count }}</p> </div>
方案2:封装到模型方法(复用性高、性能更好)
推荐用这种方案,一次查询就能拿到两个统计值,而且可以在任意位置复用:
- 先修改
Tutor模型,新增统计方法:
from django.db.models import Count, Q class Tutor(models.Model): # 原有字段保持不变,新增下面的方法 def lesson_type_stat(self): # 单次查询聚合两类课程的数量,性能优于两次单独计数 return self.lesson_set.aggregate( class_count=Count('id', filter=Q(student__type='CLASS')), online_count=Count('id', filter=Q(student__type='ONLINE')) )
- 模板中直接调用方法即可,无需修改视图:
<div> <p>线下课总数量:{{ tutorobj.lesson_type_stat.class_count }}</p> <p>线上课总数量:{{ tutorobj.lesson_type_stat.online_count }}</p> </div>
内容的提问来源于stack exchange,提问作者John Nathalang Sullivan
相关产品推荐
相关产品推荐

