Django modelform remove";“必需”;基于其他字段选择的属性
我有几个字段的ModelForm。有些字段是必需的,有些不是。另外,我有不同选择的选择字段,我想根据这个选择字段选择一些字段是否为“必需” 我尝试使用clean()的Form方法Django modelform remove";“必需”;基于其他字段选择的属性,django,django-forms,django-models,Django,Django Forms,Django Models,我有几个字段的ModelForm。有些字段是必需的,有些不是。另外,我有不同选择的选择字段,我想根据这个选择字段选择一些字段是否为“必需” 我尝试使用clean()的Form方法 def clean(self): cleaned_data = self.cleaned_data some_field = cleaned_data.get("some_field") if some_field == 'some_value': self.fields['
def clean(self):
cleaned_data = self.cleaned_data
some_field = cleaned_data.get("some_field")
if some_field == 'some_value':
self.fields['other_field'].required = False
return cleaned_data
但是它不起作用您的想法是正确的,但问题是,在表单清理之前,单个字段验证已经运行。你有几个选择。您可以将该字段设置为非必填字段,并在
表单中处理该字段的逻辑。或者,您可以根据需要保留该字段,并删除该字段在清理过程中可能引发的验证错误
def clean(self):
cleaned_data = self.cleaned_data
some_field = cleaned_data.get("some_field")
if some_field == 'some_value':
if 'other_field' in self.errors:
del self.errors['other_field']
cleaned_data['other_field'] = None
return cleaned_data
这会有一些问题,因为它会删除所有错误,而不仅仅是丢失的/必需的错误。清理后的数据也有问题。您现在有一个必填字段,它不在已清理的\u数据中,这就是为什么我将其添加为None
。应用程序的其余部分将必须处理此情况。有一个没有值的必填字段似乎有些奇怪。请参阅上的Django文档。标准做法是执行以下处理:
def clean(self):
cleaned_data = self.cleaned_data
some_field = cleaned_data.get("some_field")
if some_field == 'some_value':
# 'other_field' is conditionally required.
if not cleaned_data['other_field']:
raise forms.ValidationError("'Other_field' is required.")
return cleaned_data
如果您希望以常用方式打印必填字段的错误消息,可以执行以下操作:
def clean(self):
cleaned_data = super(PasswordChangeForm, self).clean()
token = cleaned_data.get('token')
old_password = cleaned_data.get('old_password')
if not token and not old_password:
self._errors['old_password'] = self.error_class([self.fields['old_password'].error_messages['required']])
谢谢这个想法帮助我得到了它!我需要做一个类似的验证(Django 1.4),但是我测试的字段是只读的,所以我的数据中没有它(顺便说一句,我在管理中做)。知道如何访问此只读字段的值吗?10X发现解决方案-form.instance保存所有相关数据,修改后的数据包含在form.changed_数据中虽然这听起来是正确的方法,但我认为检查some_field==some_value
的逻辑可以在视图中复制。不确定什么是正确的方法?使用冗余生存还是将此验证移动到视图?@buffer:我不明白为什么视图需要重复验证逻辑,因为表单已经这样做了。如果视图有类似的检查(以确定是否使用other_field
),则在双通道系统(1通道用于验证,1通道用于消耗)AFAICT中无法避免。如果您愿意,您可以只将该逻辑移动到视图,但是您可以对使用相同表单的多个视图重复相同的逻辑。这个答案非常非常有用!谢谢!