将任意数据添加到ModelForm最简洁的方法是什么?

时间:2011-10-10 15:38:51

标签: python django django-1.3 django-forms

想象一下,我们正在开发一个消息系统,每个Message都有sender的外键。

我们正在使用ModelForm,并且MessageForm可以从Message推断其字段。
当然,我们不希望用户通过发布不同的发件人ID 来欺骗sender

因此,我们必须从sender中排除ModelForm,并在帖子中填写session

我应该在何处以及如何将任意数据分配到ModelForm字段?

在我的示例中,我可能想要访问session,因此我们也需要访问request
这是否意味着代码必须在视图中,就在创建表单之后?

我们如何从代码中分配表单字段并确保它覆盖POST数据?

(当然,这个例子非常虚构,只是为了说明这个问题。)

2 个答案:

答案 0 :(得分:1)

只需从sender中排除ModelForm字段,当您在POST端点的视图中实例化对象时(保存之前),请确保填充sender字段使用适当的会话或用户ID。

当您排除该字段时,无法将该字段添加到帖子数据[1],因此用户无法欺骗它。

[1]使用JavaScript,理论上可以添加&sender=someSenderId,但在您看来,您不需要查找发件人字段。它不会被序列化到ModelForm对象中。

答案 1 :(得分:1)

您可以按原样排除它,然后在视图中处理表单时执行:

obj = form.save(commit=False)
obj.sender = request.user
obj.save()

或者,您可以在表单的save方法中执行此操作;为此,您需要在表单中暂时保存请求对象。如下所示:

class MyForm(forms.ModelForm):
  def __init__(self, request, *args, **kwargs):
    self._request = request
    super(MyForm, self).__init__(*args, **kwargs)

  def save(self, commit=False):
    obj = super(MyForm, self).save(commit=False)
    obj.sender = self._request.user
    if commit:
      obj.save()

    return obj

我更喜欢第二种方式,因为它有助于将关于该模型的逻辑和它的数据封装在一个整洁的地方。