7

my Code:

__init__.py

from flask import Flask
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)

from user.user import mod as user
from user.models import User as userModel

app.register_blueprint(user, url_prefix='/user')

admin = Admin(app, name='My app')
admin.add_view(ModelView(userModel, db.session, name='userAdmin'))

user.py:

from flask import Blueprint, json
from flask.views import MethodView

mod = Blueprint('user', __name__)

class UserAPI(MethodView):
    def get(self):
        users = [
            {'nickname': 'Chan'},
            {'nickname': 'Hzz'},
        ]
        return json.dumps(users)

mod.add_url_rule('/users/', view_func=UserAPI.as_view('users'))

models.py:

from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email

    def __repr__(self):
        return "<User %s>" % self.username

i have a blueprint in my user app, and i've registered it, but when i want to add this to my admin to manage the user data, it throws the below exception:

Traceback (most recent call last):
  File "run.py", line 2, in <module>
    from app import app
  File "/home/chenhj/flask/multiapp/app/__init__.py", line 21, in <module>
    admin.add_view(ModelView(userModel, db.session, name='chj'))
  File "/home/chenhj/.virtualenvs/multiapp/local/lib/python2.7/site-packages/flask_admin/base.py", line 526,     in add_view
    self.app.register_blueprint(view.create_blueprint(self))
  File "/home/chenhj/.virtualenvs/multiapp/local/lib/python2.7/site-packages/flask/app.py", line 62, in     wrapper_func
    return f(self, *args, **kwargs)
  File "/home/chenhj/.virtualenvs/multiapp/local/lib/python2.7/site-packages/flask/app.py", line 885, in     register_blueprint
    (blueprint, self.blueprints[blueprint.name], blueprint.name)
AssertionError: A blueprint's name collision occurred between <flask.blueprints.Blueprint object at 0x25e5d90> and <flask.blueprints.Blueprint object at 0x21b89d0>.  Both share the same name "user".  Blueprints that are created on the fly need unique names.

i am crazy about that

Chan
  • 117
  • 2
  • 6
  • I think the answer in error log is more then clear... a lot of `user` names- just try to change some:) – Andersson Jul 01 '15 at 06:39
  • yeah, i've fixed it, i've tried to rename the admin's name before and i failed, but the easiest way is to change the blueprint's name :) – Chan Jul 01 '15 at 06:54

3 Answers3

15

If you have a blueprint that has a name of users already then your 'admin' blueprint for your admin users model view needs to be called something different.
You can achieve this with the endpoint var in ModelView Flask-Admin - ModelView

admin.add_view(ModelView(Users, db.session, endpoint="users_"))

Jeff R.
  • 963
  • 7
  • 11
6

The collision is because you have a module name user and a blueprint called user. Rename the blueprint to user_blueprint. From the code it seems you have a folder called user, a module called user and a blueprint called user. You can avoid problems later on with some descriptive names. Otherwise it is just plain confusing.

TheGeorgeous
  • 3,927
  • 2
  • 20
  • 33
  • 1
    Wow, i've tried lots of methods but this. it works! thanks – Chan Jul 01 '15 at 06:48
  • 1
    yeah, maybe all of the blueprint's name should add suffix '_blueprint' to make it unique! that's a good habit to coding – Chan Jul 01 '15 at 06:51
4

You can also override the admin blueprint names in a ModelView subclass:

from flask_admin.contrib.sqla import ModelView

class AppModelView(ModelView):
    def create_blueprint(self, admin):
        blueprint = super(AppModelView, self).create_blueprint(admin)
        blueprint.name = '{}_admin'.format(blueprint.name)
        return blueprint

    def get_url(self, endpoint, **kwargs):
        if not (endpoint.startswith('.') or endpoint.startswith('admin.')):
            endpoint = endpoint.replace('.', '_admin.')
        return super(AppModelView, self).get_url(endpoint, **kwargs)
Patches
  • 176
  • 7