gon*_*nzo 2 python flask flask-sqlalchemy flask-admin
我正在尝试使用SQLAlchemy针对'用户'和'角色'模型设置flask-admin模型视图。我得到的不是功能管理员视图:
ValueError: Invalid model property name <class 'app.models.Role'>.desc
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
Traceback (most recent call last):
File "/Users/dbg/Projects/Python/Current/ziff/flaskbase/manage.py", line 18, in <module>
app = create_app(os.getenv('APP_CONFIG') or 'default')
File "/Users/dbg/Projects/Python/Current/ziff/flaskbase/app/__init__.py", line 49, in create_app
admin.add_view(RoleAdmin(Role, db.session))
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/view.py", line 288, in __init__
menu_icon_value=menu_icon_value)
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 570, in __init__
self._refresh_cache()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 640, in _refresh_cache
self._refresh_forms_cache()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 580, in _refresh_forms_cache
self._create_form_class = self.get_create_form()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 856, in get_create_form
return self.get_form()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 848, in get_form
return self.scaffold_form()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/view.py", line 607, in scaffold_form
extra_fields=self.form_extra_fields)
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/form.py", line 427, in get_form
for name, p in properties:
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/form.py", line 422, in <genexpr>
properties = ((x, find(x)) for x in only)
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/form.py", line 419, in find
raise ValueError('Invalid model property name %s.%s' % (model, name))
ValueError: Invalid model property name <class 'app.models.Role'>.desc
Run Code Online (Sandbox Code Playgroud)
我正在使用带有蓝图的烧瓶应用程序工厂方法。这是我的应用程序工厂。
我__init__.py尝试在第49行创建视图的文件:
ValueError: Invalid model property name <class 'app.models.Role'>.desc
Run Code Online (Sandbox Code Playgroud)
我的ModelView类:
Traceback (most recent call last):
File "/Users/dbg/Projects/Python/Current/ziff/flaskbase/manage.py", line 18, in <module>
app = create_app(os.getenv('APP_CONFIG') or 'default')
File "/Users/dbg/Projects/Python/Current/ziff/flaskbase/app/__init__.py", line 49, in create_app
admin.add_view(RoleAdmin(Role, db.session))
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/view.py", line 288, in __init__
menu_icon_value=menu_icon_value)
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 570, in __init__
self._refresh_cache()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 640, in _refresh_cache
self._refresh_forms_cache()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 580, in _refresh_forms_cache
self._create_form_class = self.get_create_form()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 856, in get_create_form
return self.get_form()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/model/base.py", line 848, in get_form
return self.scaffold_form()
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/view.py", line 607, in scaffold_form
extra_fields=self.form_extra_fields)
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/form.py", line 427, in get_form
for name, p in properties:
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/form.py", line 422, in <genexpr>
properties = ((x, find(x)) for x in only)
File "/usr/local/share/anaconda/envs/flaskbase27/lib/python2.7/site-packages/Flask_Admin-1.0.9-py2.7.egg/flask_admin/contrib/sqla/form.py", line 419, in find
raise ValueError('Invalid model property name %s.%s' % (model, name))
ValueError: Invalid model property name <class 'app.models.Role'>.desc
Run Code Online (Sandbox Code Playgroud)
编辑
Models.py
from flask import Flask
from flask.ext.bootstrap import Bootstrap
from flask.ext.mail import Mail
from flask.ext.moment import Moment
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.security import Security
from flask.ext.admin import Admin
from flask_s3 import FlaskS3
from flask.ext.cdn import CDN
from flask.ext.assets import Environment
from flask.ext.assets import PythonLoader as PythonAssetsLoader
from config import config
# app setup
bootstrap = Bootstrap()
mail = Mail()
moment = Moment()
db = SQLAlchemy()
security = Security()
admin = Admin()
s3 = FlaskS3()
cdn = CDN()
assets_env = Environment()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
app.name = app.config['APP_NAME']
config[config_name].init_app(app)
from .models import user_datastore, User, Role
from .auth.views import RoleAdmin, UserAdmin
bootstrap.init_app(app)
mail.init_app(app)
moment.init_app(app)
db.init_app(app)
security.init_app(app, user_datastore)
admin.init_app(app)
s3.init_app(app)
cdn.init_app(app)
assets_env.init_app(app)
# Here's where I'm trying to create the views
admin.add_view(RoleAdmin(Role, db.session))
admin.add_view(UserAdmin(User, db.session))
from . import assets
assets_loader = PythonAssetsLoader(assets)
for name, bundle in assets_loader.load_bundles().iteritems():
assets_env.register(name, bundle)
# attach asset bundles, routes, and custom error pages here
from main import main as main_blueprint
app.register_blueprint(main_blueprint)
import main.assets as main_assets
assets_loader = PythonAssetsLoader(main_assets)
for name, bundle in assets_loader.load_bundles().iteritems():
assets_env.register(name, bundle)
from auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
return app
Run Code Online (Sandbox Code Playgroud)
更新
from flask.ext.admin.contrib.sqla import ModelView
__author__ = 'dbg'
class RoleAdmin(ModelView):
column_display_pk = True
form_columns = ['id', 'desc']
class UserAdmin(ModelView):
column_display_pk = True
form_columns = ['id', 'email', 'active', 'last_login_at', 'login_count', 'roles']
Run Code Online (Sandbox Code Playgroud)
lou*_*ton 12
这是使用蓝图的另一种方法:
# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
db = SQLAlchemy()
admin = Admin(name='my-app', template_mode='bootstrap3')
def create_app():
app = Flask(__name__)
db.init_app(app)
admin.init_app(app)
# Add the admin panel
from app.admin import bp as admin_bp
app.register_blueprint(admin_bp)
return app
Run Code Online (Sandbox Code Playgroud)
# app/admin/__init__.py
from flask import Blueprint
bp = Blueprint('admin_bp', __name__)
from app.admin import routes
Run Code Online (Sandbox Code Playgroud)
# app/admin/routes.py
from flask_admin.contrib.sqla import ModelView
from app import db, admin
from app.models import City
admin.add_view(ModelView(City, db.session))
Run Code Online (Sandbox Code Playgroud)
好吧,这很老了,但是我要这样做:
# Inside app/auth/__init__.py (auth module includes admin):
#...
from app import db
from flask import Blueprint
from .my_custom_model_views import MyModelView
from ..models import MyModel
#...
auth = Blueprint('auth', __name__)
from . import views
#...
auth.custom_model_views = []
auth.custom_model_views += [MyModelView(MyModel, db.session)]
#...
from . import forms
# Inside app/__init__.py
# ...
admin = Admin(name='Name', ...)
# ...
def create_app(config_name):
# ...
app = Flask(__name__)
# ...
admin.init_app(app)
# And here's the important part
with app.app_context():
from .auth import auth as auth_blueprint
admin.add_views(*auth_blueprint.custom_model_views)
Run Code Online (Sandbox Code Playgroud)
重要的部分是以某种方式存储要添加的视图(在这里,我只是将它们附加到蓝图上),然后使用APP CONTEXT添加它们。否则,一切都会发疯(在没有应用程序上下文的情况下,有可能多次添加相同的模型,从而在应用程序实例化期间导致难看的名称冲突错误)。
值得注意的是,您在此处添加的所有视图都将在flask的管理菜单中显示,就好像它是模型视图一样,即使它是其他某种视图也是如此。您可以通过更改视图的is_visible和is_accessible方法来解决此问题。