How do I properly set up flask-admin views with using an application factory?

2024/10/8 13:29:40

I'm trying to setup flask-admin model views with SQLAlchemy against 'user' and 'role' models. Instead of a function admin view I'm getting:

ValueError: Invalid model property name <class 'app.models.Role'>.desc

Stack trace:

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_appadmin.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_cacheself._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_cacheself._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_formreturn 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_formreturn 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_formextra_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_formfor 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 findraise ValueError('Invalid model property name %s.%s' % (model, name))
ValueError: Invalid model property name <class 'app.models.Role'>.desc

I am using a flask application factory approach with blueprints. Here's my application factory.

My __init__.py file where I try and create the views on line 49:

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, Rolefrom .auth.views import RoleAdmin, UserAdminbootstrap.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 viewsadmin.add_view(RoleAdmin(Role, db.session))admin.add_view(UserAdmin(User, db.session))from . import assetsassets_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 herefrom main import main as main_blueprintapp.register_blueprint(main_blueprint)import main.assets as main_assetsassets_loader = PythonAssetsLoader(main_assets)for name, bundle in assets_loader.load_bundles().iteritems():assets_env.register(name, bundle)from auth import auth as auth_blueprintapp.register_blueprint(auth_blueprint)return app

My ModelView classes:

from flask.ext.admin.contrib.sqla import ModelView__author__ = 'dbg'class RoleAdmin(ModelView):column_display_pk = Trueform_columns = ['id', 'desc']class UserAdmin(ModelView):column_display_pk = Trueform_columns = ['id', 'email', 'active', 'last_login_at', 'login_count', 'roles']

EDIT

Models.py

from app import db
from flask.ext.security import UserMixin, RoleMixin, SQLAlchemyUserDatastoreroles_users = db.Table('roles_users',db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))class Role(db.Model, RoleMixin):id = db.Column(db.Integer(), primary_key=True)name = db.Column(db.String(80), unique=True)description = db.Column(db.String(255))class User(db.Model, UserMixin):id = db.Column(db.Integer(), primary_key=True)email = db.Column(db.String(256), unique=True)password = db.Column(db.String(36))active = db.Column(db.Boolean())confirmed_at = db.Column(db.DateTime())last_login_at = db.Column(db.DateTime())current_login_at = db.Column(db.DateTime())last_login_ip = db.Column(db.String(45))current_login_ip = db.Column(db.String(45))login_count = db.Column(db.Integer())roles = db.relationship('Role', secondary=roles_users,backref=db.backref('users', lazy='dynamic'))user_datastore = SQLAlchemyUserDatastore(db, User, Role)

UPDATE

Found a very helpful write-up here by this good soul. Still stuck. New error.

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 83, in create_appadmin.add_view(RoleAdmin(RoleAdmin, 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 632, in _refresh_cacheself._list_columns = self.get_list_columns()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 708, in get_list_columnscolumns = self.scaffold_list_columns()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 371, in scaffold_list_columnsfor p in self._get_model_iterator():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 310, in _get_model_iteratorreturn model._sa_class_manager.mapper.iterate_properties
AttributeError: type object 'RoleAdmin' has no attribute '_sa_class_manager'
Answer

Here is another way using blueprints:

# app/__init__.pyfrom flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admindb = 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 panelfrom app.admin import bp as admin_bpapp.register_blueprint(admin_bp)return app
# app/admin/__init__.pyfrom flask import Blueprintbp = Blueprint('admin_bp', __name__)from app.admin import routes
# app/admin/routes.pyfrom flask_admin.contrib.sqla import ModelView
from app import db, admin
from app.models import Cityadmin.add_view(ModelView(City, db.session))
https://en.xdnf.cn/q/70116.html

Related Q&A

Django Rest Framework: Correct way to serialize ListFields

Based on the DRF documentation I have a created a list of email_id stored in my model in the following way Models.pyclass UserData(models.Model):emails = models.CharField(max_length=100,blank=False)In…

Flask-SQLAlchemy TimeoutError

My backend configuration is :Ubuntu 12.04 Python 2.7 Flask 0.9 Flask-SQLAlchemy Postgres 9.2Ive got this error message: TimeoutError: QueuePool limit of size 5 overflow 10 reached, connection timed ou…

Making saxon-c available in Python

I have just read that Saxon is now available for Python, and thats just great fun and good, but can anyone write a tutorial on how to make it available for Python/Anaconda/WingIDE or similar? I am use…

How to include multiple interactive widgets in the same cell in Jupyter notebook

My goal is to have one cell in Jupyter notebook displaying multiple interactive widgets. Specifically, I would like to have four slider for cropping an image and then another separate slider for rotati…

SWIG - Problem with namespaces

Im having trouble getting the following simple example to work with SWIG 1.3.40 (and I also tried 1.3.31). The Foo structure comes through as a Python module as long as I dont wrap it in a namespace, b…

Django access to subclasses items from abstract class

class Animal(models.Model):....class Meta:abstract = Trueclass Cat(models.Model, Animal):...class Dog(models.Model, Animal):....I want to be able to return all instances of querysets of all the subclas…

Django BinaryField retrieved as memory position?

Ive written a short unit test with the following code:my_object = MyObject() my_object.data = b12345my_object.save() saved_object = MyObject.objects.first()assert saved_object.data == my_object.datawhe…

difflib.SequenceMatcher isjunk argument not considered?

In the python difflib library, is the SequenceMatcher class behaving unexpectedly, or am I misreading what the supposed behavior is?Why does the isjunk argument seem to not make any difference in this…

PyCharm Code Folding/Outlining Generates Wrong Boundaries

Im having a very frustrating issue with PyCharm in that it does not want to properly outline the code so that blocks fold correctly. Ive looked all over the place and couldnt find any help with this pa…

How to clear the conda environment variables?

While I was setting an environment variable on a conda base env, I made an error in the path that was supposed to be assigned to the variable. I was trying to set the $PYSPARK_PYTHON env variable on th…