计划结合flask-admin 和casbin 来开发一个权限管理系统, 遇到一个比较tricky的错误.
project/app/admin/base.py:
class ModelView(_ModelView):
page_size = 50
column_type_formatters = MY_DEFAULT_FORMATTERS
def is_accessible(self):
endpoint = self.endpoint
self.can_create = current_user.can(endpoint, "post")
self.can_edit = current_user.can(endpoint, "put")
self.can_delete = current_user.can(endpoint, "delete")
return current_user.can(endpoint, "get")
# return current_user.is_authenticated
project/app/models/auth.py:
class User(UserMixin, TimestampMixin, ActiveMixin, db.Model):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
email = Column(String(32), unique=True, nullable=False)
username = Column(String(32), unique=True, nullable=False)
auth = Column(SmallInteger, default=1)
password_hash = Column(String(200))
name = Column(String(100))
flag_id = Column(Integer, ForeignKey("flags.id"))
.........
@property
def is_active(self):
return self.active
@property
def is_authenticated(self):
return self.is_active
def can(self, obj, act):
return self.active
from app.lib.casbin import enforcer
return enforcer.enforce(self.username, obj, act)
project/app/templates/admin/master.html:
{% extends "admin/base.html" %}
{% block access_control %}
{% include "admin/_access_control.html" %}
{% endblock %}
project/app/templates/admin/_access_control.html:
{% if current_user.is_authenticated %}
<p> {{current_user.username }}</p>
{% else %}
<p>Nobody</p>
{% endif %}
程序第一次启动如果之前已经登陆而浏览器没有重启的情况下,第一次访问 http://127.0.0.1:5000/admin 的时候会出现:
sqlalchemy.orm.exc.DetachedInstanceError: Instance <User at 0x7f5ed33218a0> is not bound to a
Session; attribute refresh operation cannot proceed (Background on this error at:
https://sqlalche.me/e/14/bhk3)
检查 error trackback,在本次执行到 project/app/admin/base.py, 对应的 dump()如下:
__name__ 'app.admin.base'
__doc__ None
__package__ 'app.admin'
__loader__ <werkzeug.debug.console._ConsoleLoader object at 0x7f62d47718a0>
__spec__ ModuleSpec(name='app.admin.base', loader=
<_frozen_importlib_external.SourceFileLoader object at 0x7f62da488ac0>,
origin='/home/eros/iclass/app/admin/base.py')
__file__ '/home/eros/iclass/app/admin/base.py'
__cached__ '/home/eros/iclass/app/admin/__pycache__/base.cpython-310.pyc'
__builtins__ {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other
objects.\n\nNoteworthy: Non , '__package__': '', '__loader__': <class
'_frozen_importlib.BuiltinImporter'>, }
Enum <enum 'Enum'>
request <LocalProxy unbound>
redirect <function redirect at 0x7f62db5496c0>
url_for <function url_for at 0x7f62db221bd0>
render_template <function render_template at 0x7f62db0e5bd0>
current_user None
login_user <function login_user at 0x7f62db145120>
logout_user <function logout_user at 0x7f62db1451b0>
expose <function expose at 0x7f62d9516ef0>
_AdminIndexView <class 'flask_admin.base.AdminIndexView'>
_ModelView <class 'flask_admin.contrib.sqla.view.ModelView'>
typefmt <module 'flask_admin.model.typefmt' from '/home/eros/venv/lib/python3.10/site-
packages/flask_admin/model/typefmt.py'>
LoginForm <class 'app.forms.auth.LoginForm'>
enum_formatter <function enum_formatter at 0x7f62d953c5e0>
MY_DEFAULT_FORMATTERS <class 'NoneType'>: <function empty_formatter at
0x7f62d90fbac0>, <class 'bool'>: <function bool_formatter at 0x7f62d90fbb50>, <class 'list'>
<function list_formatter at 0x7f62d90fbbe0>, <class 'dict'>: <function dict_formatter at
0x7f62d90fbd00>, }
ModelView <class 'app.admin.base.ModelView'>
AdminIndexView <class 'app.admin.base.AdminIndexView'>
self <app.admin.views.CasbinView object at 0x7f62d4bfe770>
endpoint 'casbin_rules'
dump <function dump at 0x7f62d46b53f0>
help Type help(object) for help about object.
不能理解是什么原因current_user没有正确绑定到对应的对象上面。 不知道哪位大神能指点一二?错误只在第一个request的时候出现。后续request一切正常。