【发布时间】:2014-03-28 17:08:26
【问题描述】:
在 Django 中,测试之类的方法
a) 两个字段中至少有一个已填写,如果没有则放置错误信息;或
b) 因为一个字段已经填写,另一个字段成为必填字段,并在现在必填字段上放置错误消息
是在form.clean 方法中测试。
这是一项常见且重复的任务。是否有一个库可以简化clean 中此类测试的编写?最好是声明式的?
【问题讨论】:
标签: python django forms validation
在 Django 中,测试之类的方法
a) 两个字段中至少有一个已填写,如果没有则放置错误信息;或
b) 因为一个字段已经填写,另一个字段成为必填字段,并在现在必填字段上放置错误消息
是在form.clean 方法中测试。
这是一项常见且重复的任务。是否有一个库可以简化clean 中此类测试的编写?最好是声明式的?
【问题讨论】:
标签: python django forms validation
如果有一个库可以做到这一点,我会感到惊讶,因为它很难一概而论。例如,我构建了非常具体的错误消息以确保用户知道发生了什么:“既然你填写了 X 和 Y,你还必须包括一个 Z。”
但是,就您而言,花时间自己做这件事可能是值得的。如果我要这样做,我会创建一个 BaseForm 的子类以在这些情况下使用。这是一个非常粗略的大纲(未经测试):
class CrossRequirementsForm(BaseForm):
# subclasses set this attribute:
# cross_requirements_fields = {'foo': ('bar', 'baz',), 'height': ('weight',)}
def clean(self):
if self.cross_requirements_fields:
for required_field, if_other_fields = self.cross_requirements_fields.items():
if all([self.cleaned_data[f] for f in if_other_fields]):
if not self.cleaned_data[required_field]:
raise ValidationError('{} is required since {} are set'.format(
required_field, if_other_fields
))
那么,你的子类就可以这样做了:
class MyForm(CrossRequirementsForm):
cross_requirements_fields = {'foo': ('bar', 'baz',), 'height': ('weight',)}
如果它们覆盖 clean,请确保调用 super.clean。
【讨论】:
您可以为以下形式编写简单的 mixin:
from django.core import forms
class AwesomeFormMixin(object):
def clean(self):
for field in self.fields_to_process:
#process fields here
class MyForm(AwesomeFormMixin, forms.Form):
fields_to_process = ['this_field', 'that_field']
...
def clean(self):
super(MyForm, self).clean()
...
...
【讨论】: