Django开发拍卖系统出价功能时表单提交报KeyError错误
KeyError 产生原因
报错直接触发点为ItemDetailView的get_context_data方法中item = Item.objects.get(slug=kwargs["slug"])这行代码,核心原因是对Django类视图的参数传递逻辑不熟悉:
- 路由中定义的路径参数(如
<slug:slug>)会被Django解析后存放到视图实例的self.kwargs属性中 get_context_data方法接收的**kwargs是视图内部流转的上下文参数,默认不包含URL捕获的路径参数,直接从该kwargs中取slug键必然触发KeyError。
代码中还存在3个未触发但会导致后续功能异常的问题:
- 类属性配置的
success_url = reverse_lazy("auction:item_detail")没有传入路由必填的slug参数,表单提交成功后跳转时会报路由参数缺失错误 Bid模型定义了非空外键user,现有form_valid逻辑未给该字段赋值,保存出价记录时会触发数据库非空约束报错- 模板中form标签的
method属性多写了一个双引号,可能导致部分浏览器提交表单异常。
修复方案
1. 修复上下文取值逻辑
修改get_context_data方法,从self.kwargs中获取URL传入的slug参数,优化后代码如下:
from django.shortcuts import get_object_or_404 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 从self.kwargs获取路径参数,用get_object_or_404避免商品不存在时返回500错误 item = get_object_or_404(Item, slug=self.kwargs["slug"]) bids = Bid.objects.filter(item=item) context["item"] = item context["bids"] = bids return context
2. 修复跳转地址逻辑
删除类中写死的success_url类属性,新增get_success_url方法动态生成带slug参数的跳转地址:
from django.urls import reverse_lazy def get_success_url(self): return reverse_lazy("auction:item_detail", kwargs={"slug": self.kwargs["slug"]})
3. 补全模型必填字段赋值
修改form_valid方法,补全Bid模型必填的user字段赋值,去掉冗余的手动保存和硬编码重定向,走类视图标准处理流程:
def form_valid(self, form): buyer_id = self.request.session.get("id") if buyer_id: buyer_obj = Buyer.objects.get(id=buyer_id) form.instance.buyer = buyer_obj form.instance.item = get_object_or_404(Item, slug=self.kwargs["slug"]) # 补全必填的user外键赋值,可根据实际业务的User-Buyer关联关系调整取值逻辑 form.instance.user = self.request.user return super().form_valid(form)
4. 修复模板语法错误
去掉form标签中多余的双引号,修正后模板代码如下:
{% if request.user.buyer %} <form class="form-horizontal" action="" method="post"> {% csrf_token %} {{form.as_p}} <button class="btn btn-info">提交出价</button> </form> {% endif %}
可选优化
修改dispatch方法中的存在性判断逻辑,用exists()提升查询性能:
def dispatch(self, request, *args, **kwargs): buyer_id = request.session.get("id") if not Buyer.objects.filter(id=buyer_id).exists(): return redirect("auction:buyer_login") return super().dispatch(request, *args, **kwargs)
内容的提问来源于stack exchange,提问作者Muhammad asad akmal
相关产品推荐
相关产品推荐

