提交表单时todos_id传Null值问题排查(Django CreateView场景)
问题分析与解决办法
问题根源
你当前的代码存在两个核心问题:
- 请求生命周期不匹配:你在
get方法中给user_id赋值,但这个方法仅在**GET请求(加载表单页面)**时触发。当用户提交表单发起POST请求时,get方法不会执行,导致get_form_kwargs中传递的user_id还是初始的None,最终表单的todos_id字段值为None。 - 安全风险:把用户ID放在前端隐藏字段中,恶意用户可以通过修改前端代码篡改这个值,导致数据关联错误。
解决方案(推荐更安全的第二种)
方案一:修复视图的用户ID传递逻辑
直接在get_form_kwargs中从请求对象获取用户ID,无需依赖实例变量,这样GET和POST请求都能正确拿到用户ID:
class createToDo(CreateView): success_url = 'home' form_class = ToDoForm template_name = 'home.html' def get_form_kwargs(self): kwargs = super().get_form_kwargs() # 直接从当前请求中提取用户ID,覆盖原逻辑 kwargs['user_id'] = self.request.user.id return kwargs
注意:如果用户未登录会报错,建议先给视图添加登录验证(比如用
LoginRequiredMixin)。
方案二:后端直接关联用户(更安全)
完全不在表单中处理用户关联,而是在视图的form_valid方法中直接为待保存的实例设置用户,彻底避免前端篡改的风险:
第一步:修改表单,移除todos_id字段
class ToDoForm(ModelForm): title = forms.CharField(widget=forms.TextInput(attrs={'id':'title'})) description = forms.CharField(widget=forms.Textarea(attrs={'id':'description','cols':30,'rows':2})) date = forms.DateField(widget=forms.DateInput(attrs={'type':'date'})) class Meta(): model = ToDo fields = ('title','description','date')
第二步:修改视图,重写form_valid方法
from django.contrib.auth.mixins import LoginRequiredMixin class createToDo(LoginRequiredMixin, CreateView): success_url = 'home' form_class = ToDoForm template_name = 'home.html' def form_valid(self, form): # 保存表单前,将当前登录用户关联到todos字段 form.instance.todos = self.request.user return super().form_valid(form)
内容的提问来源于stack exchange,提问作者vaseemcholakkan
相关产品推荐
相关产品推荐

