【问题标题】:Python Flask WTForm SelectField with Enum values 'Not a valid choice' upon validationPython Flask WTForm SelectField 验证时枚举值“不是有效选择”
【发布时间】:2017-08-26 21:53:06
【问题描述】:

我的 Python Flask 应用正在使用具有内置 python Enum 支持的 WTForms。我正在尝试提交一个表单(POST),其中 SelectField 由枚举的所有值填充。

当我点击“提交”时,我得到了错误,“不是一个有效的选择。”这看起来很奇怪,因为在检查传入表单的值时,表单似乎确实包含从提供的 Enum 值列表中的有效选择。

我正在使用名为 AJBEnum 的 Enum 子类,其格式如下:

class UserRole(AJBEnum):
    admin = 0
    recipient = 1

我选择这样做是因为我在整个项目中使用了许多 Enum,并且想编写一个帮助函数来收集所有选项并将它们格式化为 WTForm SelectField 元组友好。 AJBEnum 的格式如下:

class AJBEnum(Enum):

    @classmethod
    def choices(cls, blank=True):
        choices = []
        if blank == True:
            choices += [("", "")]
        choices += [(choice, choice.desc()) for choice in cls]
        return choices

这意味着我可以在创建 SelectField 期间为 WTForms 提供UserRole 的所有选择,如下所示:

role = SelectField('Role', choices=UserRole.choices(blank=False), default=UserRole.recipient)

注意函数参数blank 提供了一个额外的空白 SelectField 选项,以防 SelectField 是可选的。在这种情况下,它不是。

当我点击提交按钮时,我会检查路由中传入的请求,并通过打印 form.data 我得到以下内容:

{'email': 'abc@gmail.com', 'password': 'fake', 'plan': 'A', 'confirm': 'fake', 'submit': True, 'id': None, 'role': 'UserRole.recipient'}

如您所见,WTForms 似乎已将 UserRole.recipient 字符串化。有没有办法强制 WTForms 将传入的 POST 请求值转换回预期的 Enum 值?

【问题讨论】:

  • 你找到解决方案了吗?

标签: python flask enums wtforms


【解决方案1】:

有没有办法强制 WTForms

您要查找的参数实际上称为 coerce,它接受可将字段的字符串表示形式转换为选项值的可调用对象。

  1. 选择值应该是Enum 实例
  2. 字段值应为str(Enum.value)
  3. 字段文本应为Enum.name

为了实现这一点,我用一些 WTForms 助手扩展了 Enum

class FormEnum(Enum):
    @classmethod
    def choices(cls):
        return [(choice, choice.name) for choice in cls]

    @classmethod
    def coerce(cls, item):
        return cls(int(item)) if not isinstance(item, cls) else item

    def __str__(self):
        return str(self.value)

然后您可以使用SelectField 编辑FormEnum 派生值:

role = SelectField(
        "Role",
        choices = UserRole.choices(),
        coerce = UserRole.coerce)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 2020-02-27
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多