【问题标题】:Custom and sortable column in Flask-AdminFlask-Admin 中的自定义和可排序列
【发布时间】:2017-02-15 03:32:15
【问题描述】:

我正在使用 Flask-Admin 和 SQLAlchemy,并且难以在列表视图中创建自定义的、可排序的字段。我是这样的用户和照片模型:

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    photos = db.relationship('Photo', backref='user', lazy='dynamic', cascade='all, delete-orphan')

class Photo(db.Model):
    __tablename__ = 'photos'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True)
    filename = db.Column(db.String(128))
    publish = db.Column(db.Boolean, index=True)
    date = db.Column(db.DateTime, default=datetime.now)

然后我创建一个自定义视图 (UserView),创建一个名为“测试”的自定义字段,并使用 column_formatters 重写它以包含照片数量。虽然结果正确,但该字段不可排序。有没有其他方法可以解决这个问题?

class UserView(sqla.ModelView):

    column_list = ('username', 'test')

    def _count_formatter(view, context, model, name):
        return model.photos.count()

    column_formatters = {
        'test': _count_formatter
    }

    def is_accessible(self):
        return login.current_user.is_authenticated

【问题讨论】:

    标签: flask sqlalchemy flask-sqlalchemy flask-admin


    【解决方案1】:

    您可以使用 SQLAlchemy 的 Hybrid Attributes,这对于定义作用于模型类的高级函数很有用。

    修改后的模型:

    from sqlalchemy.ext.hybrid import hybrid_property
    from sqlalchemy import select, func
    
    class User(db.Model):
        __tablename__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(64), unique=True, index=True)
        photos = db.relationship('Photo', backref='user', lazy='dynamic', cascade='all, delete-orphan')
    
        @hybrid_property
        def number_of_photos(self):
            return self.photos.count()
    
        @number_of_photos.expression
        def number_of_photos(cls):
            return select([func.count(Photo.id)]).where(Photo.user_id == cls.id).label('number_of_photos')
    

    我们刚刚添加了新的混合属性。我们可以像访问User 实例上的普通表列一样访问它:user.number_of_photos

    还有修改后的UserView

    class UserView(sqla.ModelView):
        column_list = ('username', 'number_of_photos')
        column_sortable_list = ['username', 'number_of_photos']
    
        def is_accessible(self):
            return login.current_user.is_authenticated
    

    这里我们必须明确定义可排序/可见列的列表。

    【讨论】:

    • 我不确定“@hybrid_property”和“@number_of_photos.expression”之间的区别。想详细说明一下吗?除此之外,它完全可以正常工作,但应该将“number_of_members”重命名为“number_of_photos”。
    • 我修正了错字,谢谢(我在本地应用程序中使用实际的ModelView 对其进行了测试)。据我了解文档@number_of_photos.expression 部分定义了number_of_photos(self) 方法中的Python 代码如何转换为实际的SQL 表达式。
    猜你喜欢
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 2012-10-20
    • 2018-01-10
    相关资源
    最近更新 更多