2016-03-24 16 views
2

Sahip ve Ekranlar arasında birden çok ilişkiye sahip olduğumuzu düşünelim (bir sahip birden çok ekrana sahip olabilir).Flask-Admin bir çok sayıya kadar sayılan alanı alandır

Her bir sahibin sahip olduğu ekran sayısını, bir hybrid_property kullanarak ve ilişkide count() yöntemini çağırarak gösteren bir sütun görüntülemek mümkündür. Ancak Web arayüzünde bu değer hesaplanan değer sıralanabilir yapmak için bir yol bulmak değil: Ben column_sortable_list içinde number_of_screens eklerseniz, aşağıdaki hata var: Burada

Traceback (most recent call last): 
    File "app.py", line 71, in <module> 
    admin.add_view(OwnerAdmin(Owner, db.session)) 
    File "C:\Python27\lib\site-packages\flask_admin\contrib\sqla\view.py", line 319, in __init__ 
    menu_icon_value=menu_icon_value) 
    File "C:\Python27\lib\site-packages\flask_admin\model\base.py", line 718, in __init__ 
    self._refresh_cache() 
    File "C:\Python27\lib\site-packages\flask_admin\model\base.py", line 795, in _refresh_cache 
    self._sortable_columns = self.get_sortable_columns() 
    File "C:\Python27\lib\site-packages\flask_admin\contrib\sqla\view.py", line 539, in get_sortable_columns 
    column, path = self._get_field_with_path(c) 
    File "C:\Python27\lib\site-packages\flask_admin\contrib\sqla\view.py", line 365, in _get_field_with_path 
    value = getattr(model, attribute) 
    File "C:\Python27\lib\site-packages\sqlalchemy\ext\hybrid.py", line 740, in __get__ 
    return self.expr(owner) 
    File "app.py", line 48, in number_of_screens 
    return self.screens.count() 
    File "C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py", line 193, in __getattr__ 
    key) 
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Owner.screens has an attribute 'count' 

sorunu göstermek için bir örnek kod :

from flask import Flask 
from flask_sqlalchemy import SQLAlchemy 
from sqlalchemy.ext.hybrid import hybrid_property 

import flask_admin as admin 
from flask_admin.contrib import sqla 
from flask_admin.contrib.sqla.filters import IntGreaterFilter 

# Create application 
app = Flask(__name__) 

# Create dummy secrey key so we can use sessions 
app.config['SECRET_KEY'] = '123456790' 

# Create in-memory database 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sample_db_2.sqlite' 
app.config['SQLALCHEMY_ECHO'] = True 
db = SQLAlchemy(app) 


# Flask views 
@app.route('/') 
def index(): 
    return '<a href="/admin/">Click me to get to Admin!</a>' 


class Screen(db.Model): 
    __tablename__ = 'screen' 
    id = db.Column(db.Integer, primary_key=True) 
    width = db.Column(db.Integer, nullable=False) 
    height = db.Column(db.Integer, nullable=False) 
    owner_id = db.Column(db.Integer, db.ForeignKey('owner.id')) 
    owner = db.relationship('Owner', 
     backref=db.backref('screens', lazy='dynamic')) 

    @hybrid_property 
    def number_of_pixels(self): 
     return self.width * self.height 


class Owner(db.Model): 
    __tablename__ = 'owner' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.Unicode) 

    @hybrid_property 
    def number_of_screens(self): 
     return self.screens.count() 


class ScreenAdmin(sqla.ModelView): 
    ''' Flask-admin can not automatically find a hybrid_property yet. You will 
     need to manually define the column in list_view/filters/sorting/etc.''' 
    list_columns = ['id', 'width', 'height', 'number_of_pixels'] 
    column_sortable_list = ['id', 'width', 'height', 'number_of_pixels'] 

    # make sure the type of your filter matches your hybrid_property 
    column_filters = [IntGreaterFilter(Screen.number_of_pixels, 
             'Number of Pixels')] 

class OwnerAdmin(sqla.ModelView): 
    ''' Flask-admin can not automatically find a hybrid_property yet. You will 
     need to manually define the column in list_view/filters/sorting/etc.''' 
    list_columns = ['id', 'name', 'number_of_screens'] 
    column_sortable_list = ['id', 'name', 'number_of_screens'] 


# Create admin 
admin = admin.Admin(app, name='Example: SQLAlchemy2', template_mode='bootstrap3') 
admin.add_view(ScreenAdmin(Screen, db.session)) 
admin.add_view(OwnerAdmin(Owner, db.session)) 

if __name__ == '__main__': 

    # Create DB 
    db.create_all() 

    # Start app 
    app.run(debug=True) 

cevap

4

Sen number_of_screens hibrit özellik için bir hybrid property expression değiştirici eklemeniz gerekir. Bu, belirli bir sahip için ekran sayısını hesaplamak için gerekli SQL'i yayan bir yöntemdir. Örneğin.

class Owner(db.Model): 
    __tablename__ = 'owner' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.Unicode) 

    @hybrid_property 
    def number_of_screens(self): 
     return len(self.screens) 

    @number_of_screens.expression 
    def number_of_screens(cls): 
     return db.select([db.func.count(Screen.id)]).where(Screen.owner_id == cls.id).label("number_of_screens") 
+0

Teşekkürler, tam da aradığım şey buydu! – jbfuzier

+0

'TypeError: count() tam olarak bir argüman alır (0 verilir)' :( –

+0

'' hybrid_property' altından 'return len (self.screens)' ile çalışmak için var. –

İlgili konular