Flask:多个表单字段的条件验证

Ser*_*usz 5 python forms validation flask flask-wtforms

让我从平常开始 - 我是Python和Flask的新手.在发布这个问题之前(我第一次来这里)我花了好几个小时搜索和试验,遗憾的是到目前为止没有运气.

我正在构建Web表单,用户可以在其中定义防火墙规则,随后将其记录在数据库中.我正处于验证阶段,我来到这里的墙上......希望有人能够帮助我.

我的(此处简化)表单有2个字段 - src_ip和dst_ip:

class FirewallRule(Form)
    src_ip = StringField('Source IP')
    dst_ip = StringField('Destination IP')
Run Code Online (Sandbox Code Playgroud)

我的验证要求是:

  1. 必须填写至少1个字段(两者都很好)
  2. 填充的字段必须包含有效的IP地址

wtforms.validators.IPAddress()和自定义验证函数似乎是我的朋友,但我很难找到一种方法将它们连接在一起.

基本上我正在尝试构建条件验证:

  1. 如果不是(src_ip OR dst_ip); 返回False
  2. 如果src_ip和src_ip无效的IP地址; 返回False
  3. 如果dst_ip和dst_ip无效的IP地址; 返回False
  4. 返回True

显然我想重新使用IPAddress()[或者通常是任何内置的验证器],而不是自己编写.

我相信有人必须在此之前完成它...不幸的是我无法找到正确方向的任何指针.

提前致谢.

Mig*_*uel 13

您缺少一个非常有用的验证器:可选.此验证器允许您说一个字段可以为空,但如果它不为空,则应使用其他验证器.

关于至少填写了一个字段的部分我将使用自定义验证方法,我认为没有任何股票验证器可以帮助解决这个问题.

所以它会是这样的:

class FirewallRule(Form)
    src_ip = StringField('Source IP', validators=[Optional(), IPAddress()])
    dst_ip = StringField('Destination IP', validators=[Optional(), IPAddress()])

    def validate(self):
        if not super(FirewallRule, self).validate():
            return False
        if not self.src_ip.data and not self.dst_ip.data:
            msg = 'At least one of Source and Destination IP must be set'
            self.src_ip.errors.append(msg)
            self.dst_ip.errors.append(msg)
            return False
        return True
Run Code Online (Sandbox Code Playgroud)

如果要避免使用自定义验证函数,请考虑创建验证程序类以检查是否至少设置了一个字段列表是相当容易的.如果您想要遵循此路线,可以查看EqualTo验证器的实现以获取灵感.