4

我正在开发一个消息传递系统,我想根据当前登录的用户设置消息的发起者。

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方法中这样做,但是我无权访问请求变量。在另一个 CreateView 帖子中,建议是覆盖该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用用户信息更新变量的最佳(最干净和最实用)的方法是什么?

4

1 回答 1

3

在与yuji-tomita-tomita的讨论中,他提出了以下建议,我想分享一下:

第一种方法依赖于他的原始代码,将userkwarg 发送到带有 的表单get_form_kwargs,然后您必须修改您的表单模型,如下所示:

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,它就拥有了所有的数据,并且会成功地插入到数据库中。

如果有人有不同的做法,我很想听听!

于 2013-01-18T01:17:36.397 回答