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

2024-05-13 20:55:13 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我有这样的模型和形式:

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()方法中设置此“active”标志。


Tags: selfcleanfalsetrue消息messagedataif
3条回答

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

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

然后在clean中,只需将user更改为self.user。 这还有另外一个好处。假设明天您要根据用户分配更多字段,您不需要向视图添加任何内容,只需将其添加到表单。

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

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

编辑2:如果你真的不想让字段出现在表单中 在这种情况下,与其重写clean,不如重写save?

def save (self):
    super(BaseForm, self).save()
    if user.is_admin():
        self.instance.active=True
    super(BaseForm, self).save()

不要在窗体的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

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

使用这个:

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)

相关问题 更多 >