Python Flask WTForm SelectField 在验证时具有枚举值“不是有效选择”

2024-03-18

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

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

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

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

我选择这样做是因为我在项目中使用了许多枚举,并且想要编写一个辅助函数来收集所有选择并将它们格式化为 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

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

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

Note函数参数blank如果 SelectField 是可选的,则提供额外的空白 SelectField 选项。在这种情况下,事实并非如此。

当我点击“提交”按钮时,我会检查路由中传入的传入请求并打印form.data我得到了这个内容:

{'email': '[email protected] /cdn-cgi/l/email-protection', 'password': 'fake', 'plan': 'A', 'confirm': 'fake', 'submit': True, 'id': None, 'role': 'UserRole.recipient'}

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


有没有办法强制 WTForms

您正在寻找的参数实际上被称为coerce,并且它接受一个可调用函数,将字段的字符串表示形式转换为选项的值。

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

为了实现这一点,我扩展了Enum和一些WTForms帮手:

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)

class UserRole(FormEnum):
    Owner = 1
    Contributor = 2
    Guest = 3

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

role = SelectField(
        "Role",
        choices = UserRole.choices(),
        coerce = UserRole.coerce)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python Flask WTForm SelectField 在验证时具有枚举值“不是有效选择” 的相关文章

随机推荐