[英]Set field value in Django Form clean() method, if this field not passed in constructor
我需要设置字段值,而不是传递给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()方法中设置这个“ active ”标志。
之前的答案可行,但我喜欢在表单中封装所有表单的内部操作,比如显示什么和不显示什么。 我知道你提到过你不想向构造函数发送字段值,但是如果你不介意发送用户,你的解决方案就可以了。 即你的构造函数:
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()
不要在表单的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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.