如何在常规Django Form中关联已登录用户与提交表单
解决非ModelForm下关联登录用户到表单数据的问题
我明白你遇到的困惑——大部分示例都是用ModelForm来自动处理关联字段,但用普通Form的时候确实需要手动处理用户关联的逻辑。咱们先拆解你代码里的问题,再一步步修正:
你当前代码的核心问题
你尝试给tenant_form.author = request.user的操作是无效的:
- 你的
TenantForm类里并没有定义author字段,这个赋值对表单对象来说根本不存在 - 紧接着你又用
TenantForm(request.POST)重新实例化了表单,直接覆盖了之前的tenant_form对象,之前的赋值完全被丢弃了
正确的解决方案
其实逻辑很清晰:表单只负责收集和验证用户需要输入的字段,当验证通过后,我们手动把当前登录用户添加到要保存的数据中,再创建模型实例。因为author字段不需要用户输入,所以完全不用在Form里定义它。
修改后的views.py代码如下:
@login_required def tenant_create_form_view(request): tenant_form = TenantForm() if request.method == 'POST': tenant_form = TenantForm(request.POST) if tenant_form.is_valid(): # 先获取表单验证后的合法数据 form_data = tenant_form.cleaned_data # 手动将当前登录用户加入数据字典 form_data['author'] = request.user # 用完整数据创建模型实例 AppyModel.objects.create(**form_data) # 这里可以添加成功后的操作,比如重定向到列表页 # return redirect('appy-list') else: print(tenant_form.errors) context = { 'form': tenant_form } return render(request, 'fill_appy.html', context)
为什么这样可行?
- 表单只处理用户可见的输入字段(
first_name、last_name),确保这些数据符合模型要求 - 验证通过后,我们从
cleaned_data拿到合法数据,手动补充author字段的值(当前登录用户request.user) - 最后把包含用户信息的完整数据传给
AppyModel.objects.create(),就能正确将用户和表单数据关联存储
额外优化提示
如果不想每次都重复写添加用户的逻辑,可以在模型里封装一个类方法:
class AppyModel(models.Model): author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) date_time_form_filled = models.DateTimeField(auto_now_add=True) first_name = models.CharField(max_length=20) last_name = models.CharField(max_length=20) @classmethod def create_from_form(cls, form_data, author): return cls.objects.create(**form_data, author=author)
之后在视图里就可以用AppyModel.create_from_form(tenant_form.cleaned_data, request.user)来创建实例,代码会更整洁。
内容的提问来源于stack exchange,提问作者dabeanman
相关产品推荐
相关产品推荐

