网站后端.Flask.实战-社交博客开发-赋予角色?

人走茶凉 提交于 2020-03-12 19:51:12

1.用户在注册时,会被赋予适当的角色,管理员可通过FLASK_ADMIN全局变量中的邮件地址识别,其它用户使用默认角色

FlaskWeb/app/models.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
#
# Authors: limanman
# OsChina: http://my.oschina.net/pydevops/
# Purpose:
#
"""
from . import db, loginmanager
from flask import current_app
from flask_login import UserMixin
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from werkzeug.security import generate_password_hash, check_password_hash

@loginmanager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

class Permission(object):
    FOLLOW = 0x01
    COMMENT = 0x02
    WRITE_ARTICLES = 0x04
    MANAGE_COMMENTS = 0x08
    ADMINISTER_POWER = 0x80

class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True, nullable=False, index=True)
    permission = db.Column(db.Integer)
    default = db.Column(db.Boolean, default=False, index=True)
    users = db.relationship('User', backref='role', lazy='dynamic')

    @staticmethod
    def insert_roles():
        roles = {
            'user': (
                Permission.FOLLOW |
                Permission.COMMENT |
                Permission.WRITE_ARTICLES, True),
            'manager': (
                Permission.FOLLOW |
                Permission.COMMENT |
                Permission.WRITE_ARTICLES |
                Permission.MANAGE_COMMENTS, False),
            'administrator': (
                Permission.ADMINISTER_POWER, False)
        }
        for cur_role in roles:
            role = Role.query.filter_by(name=cur_role).first()
            if not role:
                role = Role(name=cur_role)
            role.permission = roles[cur_role][0]
            role.default = roles[cur_role][-1]
            db.session.add(role)
            db.session.commit()

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, nullable=False, index=True)
    username = db.Column(db.String(64), unique=True, nullable=False, index=True)
    password_hash = db.Column(db.String(128), nullable=False)
    is_confirmed = db.Column(db.Boolean, default=False)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)
        if not self.role:
            if self.email == current_app.config['FLASK_ADMIN']:
                self.role = Role.query.filter_by(permission=128).first()
            if not self.role:
                self.role = Role.query.filter_by(default=True).first()

    @property
    def password(self):
        raise AttributeError(u'password 不允许读取.')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def generate_confirm_token(self, expires_in=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expires_in=expires_in)
        data = s.dumps({'confirm_id': self.id})
        return data

    def verify_confirm_token(self, token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except BaseException, e:
            return False
        if data.get('confirm_id') != self.id:
            return False
        self.is_confirmed = True
        db.session.add(self)
        db.session.commit()
        return True

说明:在User构造函数中判断反向引用role是否设置,基于一对多的关系,必须self.role反向引用对应的是一个基于表关系的Role对象,所以你对role属性设置(如果是超级用户就通过权限值找到并赋值,如果不是则赋予默认角色),通过关系模型self.role_id会自动设置为对应Role对象的id值,这个非常奇妙

注意:User的构造函数一定要加**kwargs,因为其实数据模型类的构造函数本身是必须写构造函数的,接收模型类变量以键值对的形式传入构造函数初始化

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!