我需要设置字段值,而不是传递给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()方法中设置此“有效”标记。
答案 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)