Skip to main content
 首页 » 编程设计

python-2.7之Flask 管理员显示枚举值而不是名称

2025年05月04日22xxx_UU

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

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:名称)。

为了澄清,我本质上是在询问是否有 Flask Admin 显示枚举的值,而不是默认情况下显示表中的名称。先感谢您...

还提供 Staff 模型以防万一它有帮助......
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要显示的类型,而不是创建单个 column_formatters您可以更新 column_type_formatters Flask-Admin 使用的。

示例

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 
 
    #  ... 

还可以考虑设置 AccessLevel 选项,如 SO answer 中所述。 .这意味着您不必在模型 View 定义中重复枚举名称/值。注意 __str____html__ 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), 
    } 
 
    # ...