Проще говоря, может ли значение, передаваемое вами в поле, быть приведено к дате и времени, не проверяется, поскольку предоставленный вами валидатор проверяет только наличие данных, а не их тип.
DateTimeField
гарантирует, что значение может быть приведено к дате и времени, но только если значение происходит из формы. Как вы можете видеть ниже, передача значения в конструктор формы через kwargs (timestamp='lmao'
) не проходит через тот же тест.
Если посмотреть на определение 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
, выполняется только для данных, поступающих из формы.
from werkzeug import MultiDict
form = InputForm(formdata=MultiDict([("timestamp", "lmao")]))
print(form.timestamp.raw_data) # ['lmao']
print(form.timestamp.process_errors) # ['Not a valid datetime value']
print(form.validate()) # False
Это означает, что вы несете ответственность за достоверность значений, которые вы передаете в поля формы через kwargs в конструктор формы.