2016-10-06 8 views
2

私はFlask-AdminとSQLAlchemyを使用しており、リストビューにカスタムの並べ替え可能フィールドを作成するのに苦労しています。私は、ユーザーと、このような写真のモデル:Flask-Adminのカスタムとソート可能な列

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 

答えて

2

あなたは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 

は、ここでは、明示的にソート可能/表示可能な列のリストを定義する必要があります。

+0

"@hybrid_property"と "@ number_of_photos.expression"の違いがわかりません。それを詳しく教えてください。それとは別に、正確に動作するはずですが、 "number_of_members"は "number_of_photos"に名前を変更する必要があります。 – NeoID

+0

私はtypoを修正しました。(実際の 'ModelView'を使ってローカルアプリケーションでテストしました。) 私は文書を理解するまで、 '@ number_of_photos.expression'部分は' number_of_photos(self) 'メソッドのPythonコードが実際のSQL式にどのように変換するかを定義しています。 – Dauros

関連する問題