WTForms 中的可选但非空字段

Tam*_*dus 4 python validation wtforms

可选验证器允许空值和该值不存在的情况(来自文档

类 wtforms.validators.Optional(strip_whitespace=True)

允许空输入并停止验证链继续。

如果输入为空,还会从字段中删除先前的错误(例如处理错误)。

我在一个字段上有一些额外的验证器,我希望即使输入是空字符串,这些验证器也能运行。如果输入是空字符串,内置Optional验证器将跳过其余验证器。是否有内置或任何其他方式来实现这一目标?

编辑:有关我的用例的更多细节

我正在使用此表单来验证PUT请求。假设我有一个用户实体,其中usernames 作为 ID,middlenames 作为可选字段。那么字段的验证器将类似于:

class UserUpdateForm(Form):
    username = fields.StringField('username', [
        validators.Optional(),
        validators.Length(min=5, max=500)
    ])
    middlename = fields.StringField('middlename', [
        validators.Optional()
    ])
Run Code Online (Sandbox Code Playgroud)

因此,我将允许PUT没有usernamemiddlename参数的请求,并且这些请求将使字段保持不变。但是,当参数存在并且是空字符串时,我希望username字段验证由于Length验证器而失败,但我允许将该middlename字段设置为空字符串。

从另一个角度来看:我想区分不存在的参数和空字符串参数。

Tam*_*dus 6

我看了一下Optional验证器的源码:

class Optional(object):
    ...
    def __call__(self, form, field):
        if not field.raw_data or isinstance(field.raw_data[0], string_types) and not self.string_check(field.raw_data[0]):
            field.errors[:] = []
            raise StopValidation()
Run Code Online (Sandbox Code Playgroud)

正如您在 中所看到的and not self.string_check(field.raw_data[0]),这里明确考虑了空字符串。我想知道如果我发送两个像这样的值会发生什么a=foo&a=&b=bar

不管怎样,对我来说快速的解决方案是实现一个新的验证器:

class OptionalButNotEmpty(object):
    """
    Allows missing but not empty input and stops the validation chain from continuing.
    """
    # Code is a modified version of `Optional` (https://github.com/wtforms/wtforms/blob/master/wtforms/validators.py#L148)
    field_flags = ('optional', )

    def __call__(self, form, field):
        if not field.raw_data:
            raise wtforms.validators.StopValidation()
Run Code Online (Sandbox Code Playgroud)