关于flask表单验证json数据不通过总是返回False的问题(flask wtforms: Validation always false)的解决方法
问题描述:
在flask中对表单的常用方式如下:
form = MyForm(request.form)
if form.validate():
# TODO
pass
其中表单form的初始化函数为 __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs);formdata参数是一个拥有getlist函数的ImmutableMultiDict对象,obj是一个模型数据对象,data参数是一个字典类型。
但经常我们需要通过表单来验证post过来的json数据,这时候常通过data参数初始化表单,即form=MyForm(data=json_data)的方式,这个时候对form调用validate()函数总是会得到False的结果,并返回一堆"This field is required",但每个字段都是输入了的,这是怎么回事呢?
原来,当我们调用validate()进行表达字段输入合法性验证的时候,会首先对每个字段的raw_data数据验证:
而每个字段的raw_data数据又是通过表单的formdata参数获取的,若是formdata为None,则所有字段的raw_data都将为空,即所有字段都会验证失败
解决方法:
重写表单初始化函数
from werkzeug.datastructures import ImmutableMultiDict
class MyForm(_ModelForm):
def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs):
"""
修复表单验证的bug
"""
self.is_valid = False
if formdata and not isinstance(formdata, ImmutableMultiDict):
formdata = ImmutableMultiDict(formdata)
elif data and formdata is None:
formdata = ImmutableMultiDict(data)
super(ModelForm, self).__init__(formdata, obj, prefix, data, meta, **kwargs)
def save(self):
"""
表单数据自动保存到模型
:return:
"""
if not hasattr(self.Meta, 'model') or not self.is_valid:
raise FormSaveException
self.instance = self.Meta.model(**self.data)
self.instance.save()
然后可以通过MyForm(formdata=json_data)或者MyForm(data=json_data)的方式初始化form对象,然后再调用validate()验证输入的合法性,这样便正常了。