知识树
1.用户角色
2.block用户
更新表结构
设计角色表结构
设计一个简单的角色表,关联到WebUser表的role_id字段,而WebUser类新增role_id字段,作为roles表的外键,同时定义初始化角色的静态函数。
Role类代码
class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) users = db.relationship('WebUser', backref='role') @staticmethod def init_roles(): roles = ['User', 'Admin'] for r in roles: role = Role.query.filter_by(name=r).first() if role is None: role = Role(name=r) db.session.add(role) db.session.commit()
WebUser表新增字段
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), default=1)
对于WebUser表类,再增加一个判断是否为admin的方法,这样就可以在路由函数中通过该方法来判断用户是否为admin用户,从而确定权限。
def is_admin(self): if self.role_id is 2: return True else: return False
添加测试页面
添加一个只有admin用户才能访问的页面,对于普通用户,则返回对应提示。
@main.route('/onlyadmin') @login_required def onlyadmin(): if current_user.is_admin(): return 'Your are admin so you can see this page' else: return 'You are not admin user, Only admin user can access this page'
这样,在真实的场景下,如果我们有些页面是只允许admin访问时,只需要通过is_admin()来做判断即可,或者直接设置,非admin用户,不展示某某页面。
新增block功能
block功能是指,如果用户处于block状态,那么将不能登陆。
新增字段和方法
在WebUser类下新增block_status字段,和is_block方法
class WebUser(UserMixin, db.Model): ... block_status = db.Column(db.Boolean, default=True) ... def is_block(self): if self.block_status: return True else: return False
在登陆函数中,添加判断
在auth的login函数中,于调用login_user函数前,添加一个判断,如果用户是block状态,则不允许登陆
if user.is_block() is False: flash('You have been blocked, please contact admin') return redirect(url_for('.login'))
手动block用户
用户列表页
添加一个userlist页面,用来展示所有的系统用户,并且每个用户都带有block和unblock按钮
{% extends "base.html" %} {% import "bootstrap/wtf.html" as wtf %} {% block title %}User List{% endblock %} {% block page_content %} <div class="container"> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alert">×</button> {{ message }} </div> {% endfor %} </div> <div class="page-header"> <h1>用户列表</h1> </div> <div class="col-md-12"> {% for u in userlist %} <p> {{ u.username }} <a class="btn btn-warning" href="{{ url_for('main.blockuser', username=u.username) }}">block</a> <a class="btn btn-primary" href="{{ url_for('main.unblockuser', username=u.username) }}">unblock</a> </p> {% endfor %} </div> {% endblock %}
block函数
首先判断用户是否为admin,然后判断是否在block当前登陆的用户,再然后判断用户是否已经处于block状态,最后再更新数据库
@main.route('/blockuser/<username>', methods=['GET', 'POST']) @login_required def blockuser(username): if current_user.is_admin(): user = WebUser.query.filter_by(username=username).first() if user.username == current_user.username: flash('Your can not block yourself') return redirect(url_for('main.userlist')) if user.is_block(): user.block_status = False db.session.add(user) db.session.commit() flash('Have block this user') return redirect(url_for('main.userlist')) else: flash('This user have been blocked') return redirect(url_for('main.userlist')) flash('Your have no permission to operate it') return redirect(url_for('main.index'))
unblock函数类似,不再赘述,可以到我的源代码中查看具体实现。
页面演示
我将完整的代码上传到GitHub上了,有兴趣的同学可以戳这里:
https://github.com/zhouwei713/flask-webauth
另外还配置了一个演示web,地址为:
也可以点击“阅读原文”进入
感兴趣的同学可以来玩玩