Django - 在ModelForm中为字段指定默认值
在我的应用程序中,有一个 CreateView
,需要把模型中的某些字段初始化为默认值,这个默认值和模型里定义的默认值不一样。
我不想让用户修改这个值,所以我把这个字段放在了 exclude
列表里。
class AForm(ModelForm):
class Meta:
model = AModel
exclude = ['a_field']
class AView(CreateView):
form_class = AForm
我的问题是:我该在哪里设置 a_field
的值呢?
我尝试在 AForm
里定义 clean
方法,像这样:
class AForm(ModelForm):
[...]
def clean(self):
d = super(AForm, self).clean()
d['a_field'] = 10
return d
但是 a_field
的值还是被设置成了模型里定义的默认值,而不是我想要的 10
。我也试过定义 clean_a_field
,但这个方法根本没有被执行。
如果我把 a_field
从 exclude
列表中移除,那么 clean
和 clean_a_field
就会生效,但表单不会通过验证,除非我在模板里渲染一个 <input name="a_field">
,这并不是最好的办法。
4 个回答
你在模型里设置了一个默认值。根据官方的文档,
比如说,a_field = models.CharField(max_length=7, default=''),这段代码的意思是:a_field这个字段最多可以有7个字符,如果没有特别指定的值,它会默认是空的。
我有一个方法来应对这种情况。请按照以下步骤操作:
从 AForm 的 排除列表 中 移除 'a_field'。
不要在 HTML 模板中 显示 'a_field'。也就是说,不要让用户通过表单在模板中更改这个值。这样可以确保普通用户不会修改这个值。
为了完全防止这种情况,重写 View 中的
get_form_kwargs
方法。 这样可以提供或重写你想要的 'a_field' 的值,并保存这个值。
例如:
class AView(CreateView): form_class = AForm def get_form_kwargs(self): kwargs = super(AView, self).get_form_kwargs() if self.request.method in {'POST', 'PUT'}: # Change post data to over-ride or provide value of 'a_field' data = self.request.POST.copy() data.update({ 'a_field': 'value' }) kwargs['data'] = data return kwargs
可以把这个字段从表单中排除掉,然后在视图中可以在保存表单之前设置这个字段的值:
form = AForm(request.POST)
if form.is_valid():
new_record = form.save(commit=False)
new_record.a_field = 10
new_record.save()
你也可以选择不使用 exclude
列表,而是通过表单定义中的 fields
属性来指定你想要包含哪些字段。具体可以查看文档的第一段,在这里。
我找到了解决这个问题的方法,虽然我对代码还是不太满意。
a_field
是模型中必填的字段,所以在模板里必须放一个<input name="a_field">
。我用的窍门是把a_field
设为非必填:
class AForm(ModelForm):
a_field = Field(required=False,
widget=forms.HiddenInput)
class Meta:
model = AModel
def clean_a_field(self):
return 10
这样我就可以不在模板里显示这个字段,而表单仍然可以正常验证。即使我用{{ form.as_p }}
来渲染表单,widget=forms.HiddenInput
也帮了我大忙。