我正在开发一个消息系统,我想根据当前登录的用户设置消息的发起者。
class Message(models.Model):
originator = models.ForeignKey(User, related_name='+')
destination = models.ForeignKey(User, related_name='+')
subject = models.CharField(max_length=100)
content = models.TextField()
我使用ModelForm和CreateView来表示:
class MessageForm(forms.ModelForm):
class Meta:
model = Message
fields = ('destination', 'subject', 'content')
因此,在保存此表单之前,需要将originator
设置为当前登录的用户。我不认为在这里覆盖模型的save
方法是合适的,所以我将采用save
方法的形式来做,但我不会有权访问请求变量。在another CreateView post中,建议是覆盖get_form_kwargs
方法:
class MyFormView(FormView):
def get_form_kwargs(self):
# pass "user" keyword argument with the current user to your form
kwargs = super(MyFormView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
然而,这不起作用,因为您无法将kwarg user
实际传递给ModelForm,因为ModelForm不接受自定义参数。
使用用户信息更新originator
变量的最佳(最干净,最实用)方法是什么?
答案 0 :(得分:3)
在与yuji-tomita-tomita的讨论中,他提出了以下建议,我想分享:
第一种方法依赖于原始代码,使用user
将get_form_kwargs
kwarg发送到表单,然后必须修改与此类似的表单模型:
class MyModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = self.kwargs.pop('user', None)
super(MyModelForm, self).__init__(*args, **kwargs)
这样原始的__init__
函数就可以获得它所期望的参数。
但他建议的首选方法是:
class MyView(CreateView):
def form_valid(self, form):
obj = form.save(commit=False)
obj.user = self.request.user
obj.save()
return super(MyView, self).form_valid(form)
这非常有效。当form.save(commit=False)
方法执行时,它会在表单对象中填充self.instance
,并使用与返回变量obj
的模型相同的实例。当您通过执行obj
更新obj.user = self.request.user
并保存它时,form
对象具有对此完全相同的对象的引用,因此此处的form
对象已经完成。当您将其传递给form_valid
的原始CreateView
方法时,它会包含所有数据并将成功插入到数据库中。
如果有人有不同的做法,我很乐意听到它!