Django视图获取子对象异常:关联Appointments计数显示错误求助
问题分析与解决办法
咱们来揪出问题的核心——你在Appointment模型的外键定义上搞混了参数用途!
先看这段模型代码:
business = models.ForeignKey(Business, on_delete=models.CASCADE, name="appointments")
这里的name参数是用来指定数据库表中的列名的,并不是设置反向关联的名称。Django默认的反向关联名称规则是模型名小写_set,也就是对于Appointment来说,默认反向关联应该是appointment_set,而不是你误以为的appointments。这就是为什么你在模板里调用business_entry.appointments.all时,统计结果一直是0——这个反向关联名称根本不存在。
两种可行的解决办法:
办法一:修改模板代码,使用默认反向关联名称
直接把模板里的代码改成默认的反向关联名称即可:
{%for business_entry in business%} {{business_entry.appointment_set.all|length}} {%endfor%}
办法二:修改模型,用related_name指定自定义反向关联名称
如果你就想在模板里用appointments这个简洁的名称,那需要把Appointment模型的外键定义改成使用related_name参数(而非name):
business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="appointments")
这样Django会把反向关联的名称设为appointments,你的模板代码不用修改就能正常统计关联数据了。
另外还要提个小问题:Appointment模型里的done = False写法不符合Django规范,普通变量不会被映射到数据库字段,应该改成布尔型字段:
done = models.BooleanField(default=False)
最后给个性能优化建议:为了避免N+1查询问题,可以在视图里用prefetch_related预取关联数据:
# 用办法二的情况 'business': Business.objects.order_by('name').prefetch_related('appointments'), # 用办法一的情况 'business': Business.objects.order_by('name').prefetch_related('appointment_set'),
内容的提问来源于stack exchange,提问作者Keyinator
相关产品推荐
相关产品推荐

