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

时间:2010-11-03 14:52:14

标签: 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

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

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

请帮助我理解,如何在 clean()方法中设置此“有效”标记。

3 个答案:

答案 0 :(得分:4)

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

def __init__(self, user):
    self.user = user
    super(BaseForm, self).__init__()

然后在您的清洁中,您只需将user更改为self.user即可。 这还有另一个好处。明天你想根据你的用户分配更多的字段,你不需要在视图中添加任何内容,只需将它添加到表单中即可。

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

active = forms.BooleanField(widget=forms.HiddenInput)

编辑2:如果你真的不想要表格中的字段 在这种情况下,为什么不重写保存?

,而不是覆盖清理
def save (self):
    super(BaseForm, self).save()
    if user.is_admin():
        self.instance.active=True
    super(BaseForm, self).save()

答案 1 :(得分:3)

请勿在表单的clean()方法中执行此操作,请在视图中执行此操作。

def your_view(request):
    if request.method == 'POST':
        form = MessageForm(data=request.POST)
        if form.is_valid():
            new_message = form.save(commit=False)
            if user.is_admin():
                new_message.active = True

但是,如果您还想使用相同的表单处理用户 admin的情况,您可以查看在表单的init()而不是视图中合并类似的逻辑,可能通过将有关用户的信息从视图传递到表单的init()

答案 2 :(得分:0)

使用此:

def message_form_factory(user):
    class MessageForm(forms.ModelForm):
        def clean(self):
            # check if user is blocked
            if user.is_admin():
                self.cleaned_data['active'] = True
            return self.cleaned_data
    return MessageForm

在您看来使用:

form = message_form_factory(request.user)()
form = message_form_factory(request.user)(request.POST)