如果此字段未在构造函数中传递,请在Django Form clean()方法中设置字段值

5 python django django-models django-forms

我需要设置字段值,而不是传递给Django Form构造函数.

我有这样的模型和形式:

class Message(models.Model):
    created     = models.DateTimeField()
    text        = models.CharField(max_length=200, blank=True, null=True)
    active      = models.BooleanField(default=False)

class MessageForm(forms.ModelForm):
    class Meta:
        model   = Message
        exclude = ('created', 'active')

    def clean(self):
        # check if user is blocked
        if user.is_admin():
            self.cleaned_data['active'] = True
        return self.cleaned_data
Run Code Online (Sandbox Code Playgroud)

预期:如果当前用户是管理员 - 我需要自动将消息设置为活动状态.用户不应该通过表单传递此参数.

实际:我看到保存的消息总是有"False"标志(我可以删除条件,在这种情况下,我也看到该消息未激活).

请帮我理解,如何在clean()方法中设置这个" active "标志.

zsq*_*are 5

前面的答案是可行的,但我喜欢在表单中封装所有表单的内部操作,例如显示什么和不显示什么。我知道您提到过您不想向构造函数发送字段值,但如果您不介意发送用户,您的解决方案就可以工作。即你的构造函数:

def __init__(self, user):
    self.user = user
    super(BaseForm, self).__init__()
Run Code Online (Sandbox Code Playgroud)

然后在你的清理中,你只需将 更改userself.user。这样做还有另一个额外的好处。假设明天您想根据您的用户分配更多字段,您不需要向视图添加任何内容,只需将其添加到表单即可。

编辑:当您添加要排除的字段时,它在已清理的数据中不可用。相反,将其小部件设置为隐藏。

active = forms.BooleanField(widget=forms.HiddenInput)
Run Code Online (Sandbox Code Playgroud)

编辑2:如果您确实不想要表单中的字段在这种情况下,为什么不覆盖保存,而不是覆盖清理?

def save (self):
    super(BaseForm, self).save()
    if user.is_admin():
        self.instance.active=True
    super(BaseForm, self).save()
Run Code Online (Sandbox Code Playgroud)