gpt4 book ai didi

验证后枚举值为 'Not a valid choice' 的 Python Flask WTForm SelectField

转载 作者:行者123 更新时间:2023-12-03 17:15:56 26 4
gpt4 key购买 nike

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

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

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

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

这意味着我可以在创建 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 值?

最佳答案

Is there a way to coerce 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)

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

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

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

关于验证后枚举值为 'Not a valid choice' 的 Python Flask WTForm SelectField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43160780/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com