Flask Admin显示枚举值而不是名称 [英] Flask Admin Display Enum Value Instead of Name

查看:222
本文介绍了Flask Admin显示枚举值而不是名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用枚举定义访问级别的模型,如下所示:

I have a model which uses an enum to define an access level as follows:

class DevelModelView(ModelView):
    edit_modal = True

    def is_accessible(self):
        return current_user.is_authenticated and current_user.access is AccessLevel.DEVEL

class DevelStaffModelView(DevelModelView):
    column_editable_list = ['access']
    column_filters = ['access']
    column_searchable_list = ['login', 'email']
    form_choices = {'access': [(AccessLevel.DEVEL.name, AccessLevel.DEVEL.value),
                               (AccessLevel.ADMIN.name, AccessLevel.ADMIN.value),
                               (AccessLevel.STAFF.name, AccessLevel.STAFF.value)]}

枚举定义如下...

class AccessLevel(Enum):
    DEVEL = 'Developer'
    ADMIN = 'Administrator'
    STAFF = 'Staff Member'

使用form_choices属性,我能够以值形式(IE:开发人员)在模式和可编辑列选择中显示,但不幸的是,显示仍使用名称(IE:名称).

Using the form_choices attribute I was able to show in both the modal and the editable column choices in value form (IE: Developer) but unfortunately the display is still using the name (IE: Name).

为澄清起见,我实质上是在询问是否有Flask Admin在显示表中默认显示一个枚举值而不是名称.预先谢谢你...

To clarify, I'm essentially asking if there is anyway to have Flask Admin display the value of an enum as opposed to the name by default in the display table. Thank you in advance...

还提供Staff模型,以防万一...

Also providing the Staff model just in case it is helpful...

class Staff(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    login = db.Column(db.String(64), unique=True)
    _password = db.Column(db.String(128))
    email = db.Column(db.String(100))
    access = db.Column('access', db.Enum(AccessLevel))

    @hybrid_property
    def password(self):
        return self._password

    @password.setter
    def password(self, plaintext):
        self._password = bcrypt.generate_password_hash(plaintext)

    def check_password(self, plaintext):
        return bcrypt.check_password_hash(self._password, plaintext)

    def __str__(self):
        return "%s: %s (%s)" % (self.access.name, self.login, self.email)

推荐答案

如果要显示几种enum类型,可以创建

If you have several enum types to display, rather than creating individual column_formatters you can update the column_type_formatters that Flask-Admin uses.

示例

from flask_admin.model import typefmt


class AccessLevel(Enum):
    DEVEL = 'Developer'
    ADMIN = 'Administrator'
    STAFF = 'Staff Member'

# ...

MY_DEFAULT_FORMATTERS = dict(typefmt.BASE_FORMATTERS)

MY_DEFAULT_FORMATTERS.update({
   AccessLevel: lambda view, access_level_enum: access_level_enum.value  # could use a function here
})


class DevelModelView(ModelView):

    column_type_formatters = MY_DEFAULT_FORMATTERS

    #  ...

还考虑按照此 SO答案中所述设置AccessLevel选项.这意味着您不必在模型视图定义中重复枚举名称/值.请注意AccessLevel类中的__str____html__方法.

Also consider setting up the AccessLevel choices as described in this SO answer. It means you don't have to repeat the enum name/values in your model view definition. Note the __str__ and __html__ methods in the AccessLevel class.

示例

from flask_admin.model import typefmt
from wtforms import SelectField


class AccessLevel(Enum):
    DEVEL = 'Developer'
    ADMIN = 'Administrator'
    STAFF = 'Staff Member'

    def __str__(self):
        return self.name  # value string

    def __html__(self):
        return self.value  # option labels


def enum_field_options(enum):
    """Produce WTForm Field instance configuration options for an Enum

    Returns a dictionary with 'choices' and 'coerce' keys, use this as
    **enum_fields_options(EnumClass) when constructing a field:

    enum_selection = SelectField("Enum Selection", **enum_field_options(EnumClass))

    Labels are produced from enum_instance.__html__() or
    str(eum_instance), value strings with str(enum_instance).

    """
    assert not {'__str__', '__html__'}.isdisjoint(vars(enum)), (
        "The {!r} enum class does not implement a __str__ or __html__ method")

    def coerce(name):
        if isinstance(name, enum):
            # already coerced to instance of this enum
            return name
        try:
            return enum[name]
        except KeyError:
            raise ValueError(name)

    return dict(choices=[(v, v) for v in enum], coerce=coerce)


class DevelModelView(ModelView):

    column_type_formatters = MY_DEFAULT_FORMATTERS

    #  ...

    form_overrides = {
        'access': SelectField,
    }

    form_args = {
        'access': enum_field_options(AccessLevel),
    }

    # ...

这篇关于Flask Admin显示枚举值而不是名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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