Python使用枚举值';不是有效的选择';经验证

Python使用枚举值';不是有效的选择';经验证,python,flask,enums,wtforms,Python,Flask,Enums,Wtforms,我的Python Flask应用程序使用WTForms,内置Python枚举支持。我试图提交一个表单(POST),其中SelectField由枚举的所有值填充 当我点击“提交”时,我得到了一个错误,“不是一个有效的选择”。这似乎很奇怪,因为在检查传入表单的值时,该表单似乎确实包含所提供枚举值列表中的有效选择 我正在使用一个名为AJBEnum的Enum子类,其格式如下: class UserRole(AJBEnum): admin = 0 recipient = 1 class

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

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

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

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

    @classmethod
    def choices(cls, blank=True):
        choices = []
        if blank == True:
            choices += [("", "")]
        choices += [(choice, choice.desc()) for choice in cls]
        return choices
role = SelectField('Role', choices=UserRole.choices(blank=False), default=UserRole.recipient)
我之所以选择这样做,是因为我在整个项目中使用了许多枚举,并希望编写一个帮助器函数来收集所有选项,并将它们格式化为对SelectField元组友好的格式。AJBEnum的格式如下:

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

    @classmethod
    def choices(cls, blank=True):
        choices = []
        if blank == True:
            choices += [("", "")]
        choices += [(choice, choice.desc()) for choice in cls]
        return choices
role = SelectField('Role', choices=UserRole.choices(blank=False), default=UserRole.recipient)
这意味着在创建SelectField期间,我可以为WTForms提供
UserRole
的所有选项,如下所示:

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

    @classmethod
    def choices(cls, blank=True):
        choices = []
        if blank == True:
            choices += [("", "")]
        choices += [(choice, choice.desc()) for choice in cls]
        return choices
role = SelectField('Role', choices=UserRole.choices(blank=False), default=UserRole.recipient)
注意:如果选择字段是可选的,则功能参数
blank
提供了一个额外的空白选择字段选项。在这种情况下,情况并非如此

当我点击Submit按钮时,我会在我的routes中检查传入的请求,并通过打印
表单。data
向我提供以下内容:

{'email': 'abc@gmail.com', 'password': 'fake', 'plan': 'A', 'confirm': 'fake', 'submit': True, 'id': None, 'role': 'UserRole.recipient'}
如您所见,WTForms似乎已将UserRole.recipient字符串化。有没有办法强制WTForms将传入的POST请求值转换回其预期的枚举值

有没有一种方法可以强制WTForms

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

  • 选择值应该是
    Enum
    实例
  • 字段值应为
    str(枚举值)
  • 字段文本应为
    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)
    

    你有没有找到解决办法?