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
相关产品推荐
相关产品推荐

