验证后具有Enum值“无效选择”的Python Flask WTForm SelectField [英] Python Flask WTForm SelectField with Enum values 'Not a valid choice' upon validation

查看:119
本文介绍了验证后具有Enum值“无效选择”的Python Flask WTForm SelectField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My Python Flask app is using WTForms with built in python Enum support. I'm attempting to submit a form (POST) where a SelectField is populated by all values of a Enum.

当我点击提交时,出现错误消息无效选择。这似乎很奇怪,因为在检查传入表单的值时,该表单似乎确实从提供的Enum值列表中包含一个有效的选择。

When I hit 'Submit' i'm given the error, 'Not a valid choice.' This seems strange because when checking the values of the incoming form, the form seemingly does contain a valid choice from the list of Enum values provided.

我正在使用名为 AJBEnum 的格式如下:

I'm using a subclass of Enum named AJBEnum which is formatted like so:

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

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

I chose to do this because I use many Enums through the project and wanted to write a helper function that gathers all choices and formats them WTForm SelectField tuple friendly. AJBEnum is formatted like so:

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 的所有选择,例如:

Which means I can give WTForms all choices for UserRole during the creating of the SelectField like so:

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

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

Note the function parameter blank provides an additional blank SelectField option in case the SelectField is optional. In this case, it is not.

当我点击提交按钮时,我会检查路径中的传入请求并通过打印表格来检查。数据,我得到了以下内容:

When I hit the Submit button I check the incoming incoming request in my routes and by printing the form.data i'm given this content:

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

看来WTForms已将UserRole.recipient字符串化。有没有一种方法可以迫使WTForms将传入的POST请求值转换回原来的Enum值?

As you can see, it appears WTForms has stringified UserRole.recipient. Is there a way to coerce WTForms into converting the incoming POST request value back to the Enum value that it was intended to be?

推荐答案


是否可以强制转换WTForms

Is there a way to coerce WTForms

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

The argument you're looking for is actually called coerce, and it accepts a callable that converts the string representation of the field to the choice's value.


  1. 选择值应为 Enum 实例

  2. 字段值应为 str(Enum。值)

  3. 字段文本应为 Enum.name

  1. The choice value should be an Enum instance
  2. The field value should be str(Enum.value)
  3. The field text should be Enum.name

要完成此操作,我用一些 WTForms Enum c>助手:

To accomplish this, I've extended Enum with some WTForms helpers:

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)

然后您可以使用<$来编辑 FormEnum 派生的值c $ c> SelectField

You can then edit a FormEnum derived value using a SelectField:

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

这篇关于验证后具有Enum值“无效选择”的Python Flask WTForm SelectField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆