【问题标题】:Flask: conditional validation on multiple form fieldsFlask:多个表单字段的条件验证
【发布时间】:2015-06-24 14:05:01
【问题描述】:

让我从平常开始 - 我对 Python 和 Flask 都是新手。在发布这个问题(我在这里的第一个问题)之前,我花了数小时搜索和试验,不幸的是到目前为止没有运气。

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

我的(这里简化了)表单有 2 个字段 - src_ip 和 dst_ip:

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

我的验证要求是:

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

wtforms.validators.IPAddress() 和自定义验证函数似乎是我的朋友,但我正在努力寻找将它们连接在一起的方法。

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

  1. 如果不是(src_ip 或 dst_ip);返回错误
  2. 如果 src_ip AND src_ip 不是有效的 IP 地址;返回错误
  3. 如果 dst_ip AND dst_ip 不是有效的 IP 地址;返回错误
  4. 返回真

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

我确信以前一定有人做过。不幸的是,我找不到任何正确方向的指针。

提前致谢。

【问题讨论】:

  • 您可以尝试重新加载表单的validate 方法并在需要时提高ValidationError
  • @dizballanze 这可以让我确保至少填写一个字段,但我将无法使用验证器来验证输入

标签: python forms validation flask flask-wtforms


【解决方案1】:

您缺少一个非常有用的验证器: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 验证器的实现以获得灵感。

【讨论】:

  • 非常感谢米格尔。我知道 Optional(),但我不知道将它与另一个验证器捆绑会产生这样的效果 - 这很聪明!
  • 感谢米格尔的回答。它帮助了我。但我有一个问题。我有 2 个字段,StringField 和 BooleanField。应该选择其中之一。您的解决方案对我有用,但我无法将 BooleanField 设置为错误(错误消息对于 StringFeild 显示正常,但对于 BooleanField 则不行)。我的意思是我无法将错误附加到该字段。有什么解决方法吗?任何帮助都会很棒:)
  • @Pradeepb 您应该能够在任何字段上设置错误。您确定问题不在您呈现复选框的方式上吗?您为复选框呈现的 HTML 必须包含错误消息,就像您为文本字段所做的那样。
猜你喜欢
  • 2015-10-18
  • 2019-02-07
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多