You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 19:18:17