Flask WTForms: DataRequired和InputRequired的区别

33

DataRequiredInputRequiredwtforms.valiadators中有什么区别?

我在注册表单中有一些字段:

username
password 
password_repeat 
submit

这些字段应该使用 DataRequired 还是 InputRequired 验证器?

1个回答

58

简短回答

除非有充分的理由,否则应该使用InputRequired

为什么?

让我们看一下来自DataRequired()文档/代码的一些注释:

请注意,InputRequired和DataRequired之间存在区别,InputRequired会检查是否提供了表单输入数据,而DataRequired会查看后置强制数据。

注意,此验证器曾被称为Required,但其行为方式(要求强制转换数据而不是输入数据)意味着其功能与Optional验证器不对称,并且还会导致对将数据强制转换为“虚假”值(如0Decimal(0)time(0)等)的某些字段引起困惑。 除非存在非常特定的原因,我们建议改用:class: InputRequired

这是什么意思?

Form类中,您会注意到两个关键字参数formdatadata。这些通常与两种方法processprocess_formdata相对应。当表单数据从网络传输时,它的格式并不总是与Field类型相对应。一个很好的例子是将值u'1'提供给IntegerField。如果您有一个NumberRange验证器,那么这将是个坏消息,因为u'1'不是数字。

process_formdata方法的主要目的是通过强制将值转换为其正确的类型来防止出现这种情况,然后再运行验证规则。这就是他们说的“查看后置强制数据”的含义。

问题出在哪里!

无论是InputRequired还是,它们都以相同的方式工作,特别是__call__实现:

def __call__(self, form, field):
    if not field.data or isinstance(field.data, string_types) and not field.data.strip():
        if self.message is None:
            message = field.gettext('This field is required.')
        else:
            message = self.message

某些字段类型会将数据强制转换为Falsey值(例如0、Decimal(0)等)。当您使用IntegerField并且表单提交了一个类似'0'的值时,问题就会出现。如果您对此应用DataRequired,则会验证失败。这是因为DataRequired在强制转换后评估if not field.data...,其中field.dataFalsey数字值0


感谢您编辑我的问题,现在我没有足够的声望来投票支持。再次感谢您提供详细的答案。 - Ryan
如果答案对您有帮助,您可以接受它作为对未来访问者的指示。 - nsfyn55
1
@nsfyn55的解释很好。不过我有一个问题。使用InputRequired()input_required()有什么区别? - Kevin
1
@kevin 验证器可以是工厂函数或可调用类。wtforms文档指出,将input_required别名化为InputRequired“允许您在将验证器从工厂移动到类时保持API兼容性,因此我们建议那些编写将共享的验证器的人使用它。” https://wtforms.readthedocs.org/en/latest/validators.html#custom-validators - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,