pythonflaskflask-loginflask-admin

flask-admin: current user return none when used in a class inherited from ModelView in flask admin


I have an error regarding flask_admin when i make my own model view by inheriting ModelView class from flask_admin.contrib.sqla in my own class name UserDeleteView in this when i use current_user( a variable of flask_login ) inside UserDeleteView it give None but when i use it in any function of UserDeleteView it works properly

like when i use it in is_accessable function of UserDeleteView class it works but when i use it in an if inside UserDeleteView class it Does not work

Here is my code for flask_admin :-

class UserDeleteView(ModelView):

    def is_accessible(self):
        return "User" in {i.split()[0] for i in current_user.permissions() }

    if "User w" not in current_user.permissions():
        can_delete=False


class PostVarificationView(BaseView):
    @expose("/")
    def index(self):
        return self.render('admin/post_varification.html')

class MyAdminIndexView(AdminIndexView):
    def is_accessible(self):
        return (current_user.is_authenticated and len(current_user.permissions())!=0)

admin = Admin(app,index_view=MyAdminIndexView(),name="Microblog")
admin.add_view(UserDeleteView( User, db.session ))
admin.add_view(PostVarificationView(name="Post Varification",endpoint="PostVarification"))

Here is the error which i got:

AttributeError: 'NoneType' object has no attribute 'permissions'

Traceback (most recent call last)
File "/home/chirag/Documents/Projects/microblog1/microblog.py", line 1, in <module>
from app import app,db
File "/home/chirag/Documents/Projects/microblog1/app/__init__.py", line 21, in <module>
from app import routes, models, errors
File "/home/chirag/Documents/Projects/microblog1/app/routes.py", line 309, in <module>
class UserDeleteView(ModelView):
File "/home/chirag/Documents/Projects/microblog1/app/routes.py", line 314, in UserDeleteView
if "User w" not in current_user.permissions():
File "/home/chirag/Documents/Project venv/microblog1/lib/python3.7/site-packages/werkzeug/local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
AttributeError: 'NoneType' object has no attribute 'permissions'

Solution

  • Code defined in a class body is executed when the module is first imported, there is no current_user hence the error. See this SO question "Why does a class' body get executed at definition time?" for further reading.

    Replace can_delete with a method and decorate with @property, current_user is then available.

    Example:

    class UserDeleteView(ModelView):
    
        def is_accessible(self):
            return "User" in {i.split()[0] for i in current_user.permissions() }
    
        @property
        def can_delete(self):
            # Your logic here
            return "User w" in current_user.permissions()