Django按订单上传支付凭证图片报QuerySet无_meta属性错误
错误根因
Django ModelForm 的instance参数仅支持接收单个模型实例对象,你使用Order.objects.filter()返回的是QuerySet集合类型(哪怕匹配结果只有1条),该类型没有模型实例专属的_meta属性,因此抛出对应报错。
除此之外代码还存在3个会导致功能异常的问题:
- 视图向模板传递的订单变量名为
orders,但模板中读取的是order.buktiURL,变量名不匹配会导致凭证图片无法正常展示 - 表单包含了
id字段,普通用户上传凭证时可篡改订单ID,存在数据安全风险 - 订单项、物流信息的查询直接使用
orid作为过滤条件,未校验订单所属权限,容易出现越权访问
修复方案
- 将订单查询逻辑从
filter()改为获取单个实例的写法,推荐用get_object_or_404自动处理订单不存在、订单不属于当前用户的非法场景,直接返回404响应 - 表单移除不必要的
id字段,仅保留凭证上传字段 - 统一视图与模板的订单变量名,修正关联查询的过滤条件
修正后代码
view.py
from django.shortcuts import get_object_or_404 def Detail(request, orid=None): data = cartData(request) cartItems = data['cartItems'] id_profil = request.user.profile # 获取当前登录用户所属的单个目标订单,不存在直接返回404 order = get_object_or_404(Order, id=orid, id_profil=id_profil) OrderItems = OrderItem.objects.filter(order=order) pengirimans = Pengiriman.objects.filter(order=order) if request.method == "POST": # 传入单个订单实例作为form的绑定对象 form = Uplaodpic(request.POST, request.FILES, instance=order) if form.is_valid(): form.save() else: form = Uplaodpic(instance=order) context = { 'order': order, 'OrderItems': OrderItems, 'pengirimans': pengirimans, 'cartItems': cartItems, 'form': form } return render(request, 'store/detail.html', context)
forms.py
from django.forms import ModelForm from .models import Order class Uplaodpic(ModelForm): class Meta: model = Order # 仅保留支付凭证上传字段,移除可被篡改的id字段 fields = ["bukti"]
detail.html(注意原文件名拼写错误为detial.html,建议同步修正文件名)
<td colspan="2"> <img src="{{ order.buktiURL }}" alt="支付凭证" class="img-thumbnail" style="max-height:100px"> </td> <td colspan="2"> <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} {{form.as_p}} <input type="Submit" id="submit" name="submit" value="上传凭证"> </form> </td> </tr>
models.py
原有模型定义无需修改。
补充:如果要保留filter写法,可在filter后调用
.first()取第一个匹配对象作为实例,即order = Order.objects.filter(id=orid, id_profil=id_profil).first(),但该写法需要额外判断订单是否为空,安全性和简洁性不如get_object_or_404。
内容的提问来源于stack exchange,提问作者Kokumi
相关产品推荐
相关产品推荐

