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

时间:2015-04-17 15:53:04

标签: python forms validation flask flask-wtforms

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

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

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

class FirewallRule(Form)
    src_ip = StringField('Source IP')
    dst_ip = StringField('Destination IP')

我的验证要求是:

  1. 必须填写至少1个字段(两者都很好)
  2. 填充的字段必须包含有效的IP地址
  3. wtforms.validators.IPAddress()和自定义验证功能似乎是我的朋友,但我很难找到将它们连接在一起的方法。

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

    1. 如果不是(src_ip或dst_ip);返回False
    2. 如果src_ip AND src_ip无效的IP地址;返回False
    3. 如果dst_ip和dst_ip无效的IP地址;返回False
    4. 返回True
    5. 显然我想重新使用IPAddress()[或者通常是任何内置的验证器],而不是自己编写。

      我相信有人必须在此之前做过..不幸的是我找不到任何正确方向的指示。

      提前致谢。

1 个答案:

答案 0 :(得分:11)

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

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

所以它会是这样的:

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

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