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

Django中基于ForeignKey创建表单 实现商铺仅可给自己添加商品

代码调整方案

你的现有代码里表单部分已经做了商铺可选范围限制(仅能选当前用户名下的商铺),核心错误出在视图的form_valid方法逻辑异常,以及空的get_context_data方法导致报错,按下面调整即可:

问题点梳理

  • Product模型不存在owner字段,form.instance.owner = self.request.user 属于无效赋值
  • 商铺查询语法错误:Store.objects.filter(Store__owner=self.request.user) 字段名拼写错误,且filter返回的是查询集而非单个商铺对象
  • 错误将form实例替换为cleaned_data字典传入父类方法,导致参数类型不匹配
  • 空的get_context_data方法返回None,会引发模板渲染错误

方案1:保留商铺下拉选择框(仅显示当前用户名下商铺)

修改views.py代码即可:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect
from django.urls.base import reverse
from django.contrib.auth import authenticate, login
from .models import Product, Store
from django.views.generic import CreateView
from .forms import AddProductForm

# 新增LoginRequiredMixin保证只有登录用户可访问
class AddProductView(LoginRequiredMixin, CreateView):
    model = Product
    form_class = AddProductForm
    template_name = 'app1/add-product.html'

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    # 简化form_valid逻辑,表单已经做了商铺可选范围限制,无需手动赋值
    def form_valid(self, form):
        if not Store.objects.filter(owner=self.request.user).exists():
            return super().form_invalid(form)
        return super().form_valid(form)

    # 补全get_context_data,或者直接删除该方法即可
    def get_context_data(self, **kwargs):
        return super().get_context_data(**kwargs)

    def get_success_url(self):
        return reverse('store', kwargs={'slug': self.object.store.slug})

方案2:隐藏商铺字段,自动填充当前用户的商铺(更推荐,完全避免误操作)

第一步修改forms.py

from .models import Product
from django import forms

class AddProductForm(forms.ModelForm):
    class Meta:
        model = Product
        # 移除store字段,不让用户手动选择
        fields = ('name', 'price', 'image',)
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Name of your product'}),
            'price': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': 'Price of your product'}),
            'image': forms.FileInput(attrs={'class': 'form-control'}),
        }

第二步修改views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls.base import reverse
from .models import Product, Store
from django.views.generic import CreateView
from .forms import AddProductForm

class AddProductView(LoginRequiredMixin, CreateView):
    model = Product
    form_class = AddProductForm
    template_name = 'app1/add-product.html'

    def form_valid(self, form):
        # 自动获取当前用户的商铺
        user_store = Store.objects.filter(owner=self.request.user).first()
        if not user_store:
            return super().form_invalid(form)
        # 手动绑定商铺到产品
        form.instance.store = user_store
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('store', kwargs={'slug': self.object.store.slug})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:15:01