Django视图获取数据库上下文报错:QuerySet对象无product属性
解决"QuerySet' object has no attribute 'product'"错误并实现发票数据展示
错误原因
PurchaseItem.objects.all()返回的是QuerySet(多个对象的集合),不是单个PurchaseItem实例,集合本身没有product属性,直接调用purchases.product必然报错。- 你在context中将单个PurchaseItem的属性嵌套到了
company字典里,但模板代码是直接遍历purchases变量,上下文里根本没有这个键,模板无法获取数据。
修正代码
1. 修改views.py
调整context结构,将查询集直接放到根层级,同时优化查询避免N+1问题:
def get_context_data(request, **kwargs): # 获取所有采购项,预关联product表优化查询 purchases = PurchaseItem.objects.all().select_related('product') context = { "company": { "name": "Mc-Services", "address": "1080, Vienna, Austria", "phone": "(818) XXX XXXX", "email": "contact@mcservice---.com" }, "purchases": purchases # 把查询集暴露给模板 } return render(request, 'purchase/pdf_template.html', context)
2. 模板代码(pdf_template.html)
原模板的遍历逻辑是正确的,无需修改:
<tbody> {% for purchase in purchases %} <tr> <td class="no" >{{purchase.product}}</td> <td class="qty" >{{purchase.quantity}}</td> <td class="total" >${{purchase.product.price}}</td> </tr> {% endfor %} </tbody>
关键说明
select_related('product'):因为PurchaseItem和Item是外键关联,使用这个方法可以一次性把关联的Item数据查询出来,避免模板循环时每次查询数据库,提升性能。- 模板中遍历的
purchases是QuerySet,每次循环的purchase是单个PurchaseItem实例,此时可以正常访问.product、.quantity等实例属性。
内容的提问来源于stack exchange,提问作者Sesshōmaru
相关产品推荐
相关产品推荐

