Heim > Fragen und Antworten > Hauptteil
from werkzeug.security import generate_password_hash,check_password_hash
from app import create_app,db
from . import login_manager
from flask.ext.login import UserMixin,AnonymousUserMixin
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from flask import current_app
from . import db
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))#增加回调函数,接收以unicode字符串形式表示的用户标识符,找到返回用户对象否则返回None
class Permission:
FOLLOW = 0x01
COMMENT = 0x02
WRITE_ARTICLES = 0x04
MODERATE_COMMENTS = 0x08
ADMINISTER = 0x80
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),unique=True)
default = db.Column(db.Boolean,default=False,index=True)
permissions = db.Column(db.Integer)
users = db.relationship('User',backref='role',lazy='dynamic')#backref 参数向 User 模型中添加一个 role 属性,从而定义反向关 系。
#这一属性可替代 role_id 访问 Role 模型,此时获取的是模型对象,而不是外键的值。
#lazy属性决定加不加载纪录,dynamic是指不加载纪录但是提供查询
@staticmethod
def insert_roles():
roles = {'User' : (Permission.FOLLOW |
Permission.COMMENT |
Permission.WRITE_ARTICLES,True),
'Moderator' : (Permission.FOLLOW |
Permission.COMMENT |
Permission.WRITE_ARTICLES |
Permission.MODERATE_COMMENTS,False),
'Administrator' :(0xff,False)
}
for r in roles:
role = Role.query.filter_by(name=r).first()
if role is None:
role = Role(name=r)
role.permissions = roles[r][0]
role.default = roles[r][1]
db.session.add(role)
db.session.commit()
def __repr__(self):
return '<Role %r>' % self.name
class User(UserMixin,db.Model):#UserMixin类中实现了一些用来记录用户登录状态方法
__tablename__='users'
id = db.Column(db.Integer,primary_key=True)
email = db.Column(db.String(64),unique = True,index=True)
username = db.Column(db.String(64),unique=True,index=True)
role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))#db.ForeignKey() 的参数 'roles.id' 表 明,这列的值是 roles 表中行的 id 值。
confirmed = db.Column(db.Boolean,default=False)
password_hash = db.Column(db.String(128))
def __init__(self,**kwargs):
super(User,self).__init__(**kwargs)
if self.role is None:
if self.email == current_app.config['FLASKY_ADMIN']:
self.role = Role.query.filter_by(permissions=0xff).first()
if self.role is None:#不明白为什么还要写一个self.role is None
self.role = Role.query.filter_by(default=True).first()
@property
def password(self):
raise AttributeError('password is not a readable attribute')
@password.setter
def password(self,password):
self.password_hash = generate_password_hash(password)
'''
python 内置的@property装饰器可以将一个方法变成属性调用,详情见http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386820062641f3bcc60a4b164f8d91df476445697b9e000
在这里User.password会引发属性错误,User.password(password)会生成密码的散列值
'''
def verify_password(self,password):
return check_password_hash(self.password_hash,password)#查看密码是否正确
def generate_confirmation_token(self,expiration=3600):
s = Serializer(current_app.config['SECRET_KEY'],expiration)
return s.dumps({'confirm':self.id})
def confirm(self,token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
data = s.loads(token)
except:
return False
if data.get('confirm') != self.id:
return False
self.confirmed=True
db.session.add(self)
return True
def generate_reset_token(self,expiration=3600):
s = Serializer(current_app.config['SECRET_KEY'],expiration)
return s.dumps({'reset':self.id})
def reset_password(self,token,new_password):
s = Serializer(current_app.config['SECRET_KEY'],expiration)
try:
data = s.loads(token)
except:
return False
if data.get('reset') != self.id:
return False
self.password = new_password
db.session.add(self)
return True
def generate_email_change_token(self,new_email,expiration=3600):
s = Serializer(current_app.config['SECRET_KEY'],expiration)
return s.dumps({'change_email':self.id,'new_email':new_email})
def change_email(self,token):
s = Serializer(current_app['SECRET_KEY'])
try:
data = s.loads(token)
except:
return False
if data.get['change_email'] != self.id:
return False
new_email = data.get['new_email']
if new_email is None:
return False
if self.query.filter_by(email=new_email).first() is not None:
return False
self.email = new_email
db.session.add(self)
return True
def can(self,permissions):
return self.role is not None and ()
User类的构造函数里,为什么在if self.role is None下还写了一个if self.role is None条件,直接else:不就行了吗?
大家讲道理2017-04-17 17:30:22
self.role = Role.query.filter_by(permissions=0xff).first()
这里不是有可能改变self.role的值么。。。。