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

Django开发拍卖站点:如何自动将表单创建者传入表单并保存?

解决方案

错误原因

你遇到的BaseModelForm.__init__() got an unexpected keyword argument 'user'错误,核心是视图中表单初始化的逻辑顺序有误,且将user字段暴露在表单中存在安全隐患——前端可篡改隐藏字段。

最优修复方案

我们可以完全避开在表单中处理user字段,直接在视图里通过当前登录用户设置创建者信息,步骤如下:

1. 修改表单(forms.py)

移除表单中所有与user相关的配置,无需将user字段加入表单:

class CreateListing(forms.ModelForm):
    category = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label="No category")
    class Meta:
        model = AuctionListing
        fields = ('title', 'description', 'starting_bid', 'url', 'category')
        widgets = {
            'title': forms.TextInput(attrs={'placeholder':'Write your listing title here...'}),
            'description': forms.Textarea(attrs={'placeholder':'Write your comment here...', 'rows':3}),
        }

2. 修改视图函数(views.py)

表单验证通过后,用commit=False先创建实例但不保存到数据库,手动设置user为当前登录用户后再完成保存:

def create_listing(request):
    if request.method == "POST":
        form = CreateListing(request.POST)
        if form.is_valid():
            # 创建实例但暂不提交到数据库
            listing = form.save(commit=False)
            # 设置创建者为当前登录用户
            listing.user = request.user
            listing.save()
            return HttpResponseRedirect(reverse("index"))
        return render(request, "auctions/create_listing.html", {"form": form})
    # GET请求时初始化空表单
    form = CreateListing()
    return render(request, "auctions/create_listing.html", {"form": form})

3. 修改模板(auctions/create_listing.html)

移除模板中的{{ form.user }}字段,因为表单已不再包含该字段:

<h1> Create new listing </h1>
<form action="" method="POST">
    {% csrf_token %}
        <label>Name*</label>
        <br>
        {{ form.title }}
    <br>
        <label >Description*</label>
        <br>
        {{ form.description }}
        <br>   
        <label >Starting bid*</label>
        <br>
        {{ form.starting_bid }}
        <br>  
        <label > Image url (optional) </label>
        <br>
        {{ form.url }}
        <br>  
        <label > Category (optional) </label>
        <br>
        {{ form.category }}
        <br> 
        <button type="submit" class="btn btn-primary save">Create your listing</button>
    
</form>

原方案的快速修复(不推荐)

如果坚持保留原表单写法,只需调整视图中表单初始化的顺序,确保仅在对应请求方法中正确传递参数:

def create_listing(request):
    if request.method == "POST":
        form = CreateListing(request.POST, user=request.user)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse("index"))
        return render(request, "auctions/create_listing.html", {"form": form})
    # GET请求时初始化表单并传递user参数
    form = CreateListing(user=request.user)
    return render(request, "auctions/create_listing.html", {"form": form})

但这种方式仍存在前端篡改隐藏字段的风险,因此优先推荐第一种方案。

内容的提问来源于stack exchange,提问作者Annelotte

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:15:53