我有自定义ZIPCodeField,但它需要让国家/地区正常工作, 验证很容易我可以将它保存在表单的 init 中的_country属性中(以相同的形式回退到country字段),它看起来像:
class ZIPCodeField(wtforms.TextField):
def pre_validate(self, form):
if not self.data:
return
country = country = getattr(form, '_country', form.data.get('country'))
country = country.upper()
if not validate_zip_code(self.data, country):
raise ValueError(self.gettext(u'Invalid ZIP code.'))
但是对于process_formdata方法存在问题(我希望通过简单的过滤器传递接收的数据以正确格式化邮政编码),我们没有表单实例,所以看起来有2个解决方案:
在字段级别保存国家/地区,例如:
class ZIPCodeField(wtforms.TextField):
def process_formdata(self, valuelist):
if valuelist:
self.data = format_zip_code(valuelist[0], self._country)
else:
self.data = ''
class TestForm(wtforms.Form):
zip_code = ZIPCodeField()
form = TestForm(MultiDict([('zip_code', '123455')]))
form.zip_code._country = u'US'
或者,覆盖进程方法并将我的额外值传递给它的数据参数,如:
class ZIPCodeField(wtforms.TextField):
def process(self, formdata, data):
# we picking country value from data here
pass
form = TestForm(MultiDict([('zip_code', '123455')]),
zip_code=zip_code={'country': u'US'})
哪一个是正确的解决方案?还是有更好的解决方案?
答案 0 :(得分:0)
所有这些都可以正常工作,但总的来说,我会建议您将数据访问逻辑从表单中删除。这使得关注点分离得很糟糕。
您的表单有一个非常具体的工作,那就是验证表单提交。在您的情况下,您想要增加表单中提交的数据然后验证它。这并不需要覆盖wtforms process
方法。我会在中间件或视图中进行国家/地区检索,将其附加到表单的提交数据,然后将表单验证为正常。如果邮政编码没有返回有效国家或未找到,我会abort(400)
就在那里。