如果某人要拥有一个具有几种“类型”用户的Flask Web应用程序,例如在学校环境中,可能会有“老师”,“学生”和“管理员”。每个用户都需要一种登录应用程序的方法,但是Flask-Login仅提供一种@login.user_loader
。我的问题是类似这样的问题,有关多用户类,但不同的是,每一种类型的用户不具有相同的模型结构为别人。例如,如果要使用flask-sqlalchemy并声明以下模型:
class Teacher(db.Model, UserMixin):
id = db.Column(db.Integer,primary_key=True)
title = db.Column(db.String(32))
pwd_hash = db.Column(db.String(128))
first_name = db.Column(db.String(128))
last_name = db.Column(db.String(128))
students = db.relationship('Student',backref='teacher',lazy='dynamic') #because a teacher will teach multiple students
class Student(db.Model, UserMixin):
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(64),unique=True)
teacher_id = db.Column(db.ForeignKey('teacher.id'),db.Integer) #for the ease of things, the student is only ever taught by one teacher
class Admin(db.Model, UserMixin):
email = db.Column(db.String(128),unique=True)
name = db.Column(db.String(128))
通常以这种方式使用user_loader,User
这里的类是通用用户类:
@login.user_loader
def load_user(id):
return User.query.get(int(id))
这意味着,你必须有一个可以登录只有一个User类,正常的做法是凝结的Student
,Teacher
和Admin
全班学生分成一个User
班,一个role
在它告诉你它们是什么级别的访问权限的模型字段。但这带来了多个问题。例如,并非所有学生都可以使用电子邮件,但学校的管理帐户需要一封电子邮件。同样,学生与教师之间的关系也会失败,因为没有一种让老师上课的模型。
那么,如何实现具有多个具有不同属性和模型字段的用户模型的方法,每个用户模型可以使用flask_login分别登录?
您User
只需要一个ID以及与该用户对应的表的关系即可。您可以通过为角色和角色关系创建表来创建此表:
class User(db.Model, UserMixin):
""""""
__tablename__ = "user"
# Core
id = db.Column(db.Integer,primary_key=True)
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
class Role(db.Model, RoleMixin):
__tablename__ = "role"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
roles_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 User(db.Model, UserMixin):
# all the args go here...
...
def has_role(self, role_name):
"""Does this user have this permission?"""
my_role = Role.query.filter_by(name=role_name).first()
if my_role in self.roles:
return True
else:
return False
接下来,创建一个装饰器来检查角色
from flask import redirect
from flask_login import current_user
from functools import wraps
def require_role(role):
"""make sure user has this role"""
def decorator(func):
@wraps(func)
def wrapped_function(*args, **kwargs):
if not current_user.has_role(role):
return redirect("/")
else:
return func(*args, **kwargs)
return wrapped_function
return decorator
步骤3:在操作中应用装饰器:
@app.route("/")
@login_required
@require_role(role="teacher")
def teachers():
"""Only allow teachers"""
# Otherwise, proceed
return render_template('teachers.html')
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句