在Django表单集中使用clean修改字段
如何在Django的表单集合中使用clean
方法来修改每个表单的字段?
class MyInlineFormSet(BaseInlineFormSet):
def clean(self):
if self.cleaned_data['inputted'] == self.cleaned_data['answer']:
self.cleaned_data['is_correct'] = True
return self.cleaned_data
这个方法不太奏效,我看到有人遍历每个表单,但他们只是验证数据,并没有进行修改。如果我遍历每个表单,那我该如何返回cleaned_data
呢?换句话说:
class MyInlineFormSet(BaseInlineFormSet):
def clean(self):
for form in self.forms:
if form.cleaned_data['inputted'] == form.cleaned_data['answer']:
form.cleaned_data['is_correct'] = True
...?
2 个回答
0
我觉得你现在的做法是对的,你在逐个处理表单并设置清理后的数据(你第二个例子中的做法)。BaseFormSet 有一个叫做 cleaned_data
的属性,它会返回每个表单清理后的数据列表。这是你想要的吗?比如:
return self.cleaned_data
它实际上返回的是:
[form.cleaned_data for form in self.forms]
如果我理解代码没错的话,这里应该有正确的数据(经过修改的)。
如果你只是想把值保存到你的模型里,我建议你不要使用 clean
方法,而是重写 save
方法:
def save_new(self, form, commit=True):
form.instance.is_correct = ...
return super(...).save_new(...)
def save_existing(...)
2
根据ssomnoremac的评论,我在BaseModelFormSet的clean方法中使用了form.instance.field_i_wanted_to_change,而不是form.cleaned_data['field_i_wanted_to_change'],这样就成功了。大概是这样的:
class MyInlineFormSet(BaseInlineFormSet):
def clean(self):
for form in self.forms:
if form.cleaned_data['inputted'] == form.cleaned_data['answer']:
form.instance.is_correct = True
在我的情况下,我已经调用了clean_field_i_wanted_to_change,所以顺序是先执行clean_field,然后是clean @ MyInlineFormSet。这个是在Django 1.11版本下的做法。