我努力理解为什么WTForms总是验证我的输入,即使它与文档中规定的默认输入格式不匹配也是如此。文档说默认格式是
class wtforms.fields.DateTimeField(default field arguments, format='%Y-%m-%d %H:%M:%S')
但是我的代码总是返回true
from wtforms import Form, validators
from wtforms.fields import DateTimeField
class InputForm(Form):
timestamp = DateTimeField('TimeStamp', validators=[validators.DataRequired()])
form = InputForm(timestamp='lmao')
form.validate()
# True
有人可以向我解释这种行为吗?
简单地说,不会检查您传递给字段的值是否可以强制为日期时间,因为您提供的验证器仅检查数据的存在,而不检查类型。
DateTimeField
确实确保可以将值强制为日期时间,但前提是该值来自表单。如下所示,通过kwargs(timestamp='lmao'
)将值传递到表单构造函数中并没有通过相同的测试。
[查看DateTimeField
的定义,唯一与该字段作为日期时间字段进行自定义处理的方法是DateTimeField
方法(也是process_formdata()
,但窗口小部件用于呈现字段):
_value()
实例化class DateTimeField(Field):
"""
A text field which stores a `datetime.datetime` matching a format.
"""
widget = widgets.TextInput()
def __init__(
self, label=None, validators=None, format="%Y-%m-%d %H:%M:%S", **kwargs
):
super(DateTimeField, self).__init__(label, validators, **kwargs)
self.format = format
def _value(self):
if self.raw_data:
return " ".join(self.raw_data)
else:
return self.data and self.data.strftime(self.format) or ""
def process_formdata(self, valuelist):
if valuelist:
date_str = " ".join(valuelist)
try:
self.data = datetime.datetime.strptime(date_str, self.format)
except ValueError:
self.data = None
raise ValueError(self.gettext("Not a valid datetime value"))
对象时,将调用表单的Form
方法,该方法调用每个表单字段的process()
方法并传递process()
(在这种情况下为formdata
)和如果可以找到该字段的值(在这种情况下为None
)。
如您所见,上面的'lmao'
定义上没有定义process()
方法,因此它调用了DateTimeField
:
Field.process()
在此方法中,参数 def process(self, formdata, data=unset_value):
"""
Process incoming data, calling process_data, process_formdata as needed,
and run filters.
If `data` is not provided, process_data will be called on the field's
default.
Field subclasses usually won't override this, instead overriding the
process_formdata and process_data methods. Only override this for
special advanced processing, such as when a field encapsulates many
inputs.
"""
self.process_errors = []
if data is unset_value:
try:
data = self.default()
except TypeError:
data = self.default
self.object_data = data
try:
self.process_data(data)
except ValueError as e:
self.process_errors.append(e.args[0])
if formdata is not None:
if self.name in formdata:
self.raw_data = formdata.getlist(self.name)
else:
self.raw_data = []
try:
self.process_formdata(self.raw_data)
except ValueError as e:
self.process_errors.append(e.args[0])
try:
for filter in self.filters:
self.data = filter(self.data)
except ValueError as e:
self.process_errors.append(e.args[0])
为data
,'lmao'
为formdata
。您可以看到对None
的调用受process_formdata()
条件的保护,因此if formdata is not None:
上定义的字段的自定义处理仅在来自表单的数据上运行。
DateTimeField
这意味着您应对通过kwargs传递给表单构造函数的表单字段值的有效性负责。