定义model
python
# @Time :2024-2024/2/27-14:49
# @Email :514422868@qq.com
# @Author :Justin
# @file :user.py
# @Software :01-fishbook
from app.model.base import Base
from sqlalchemy import Column, Integer, SmallInteger, String
from werkzeug.security import generate_password_hash, check_password_hash
class User(Base):
# auto_increment=True 不需要auto_increment
id = Column(Integer, primary_key=True)
nickname = Column(String(32), index=True, nullable=False, unique=True)
email = Column(String(32), index=True, nullable=False, unique=True)
status = Column(SmallInteger, default=1)
_password = Column("password", String(256))
@property
def password(self):
return self._password
# 这里必须是属性名称
@password.setter
def password(self, raw):
self._password = generate_password_hash(raw)
def check_password(self, raw: str):
# 必须是先是加密之后的密码,再是原始密码
return check_password_hash(self.password, raw)
里面的注释要好好看,
注意@property是 obj.password时触发,因为password是密文存储的,
所以,在赋值时指向password(self,raw)的方法,将它加密
使用的generate_password_hash 和 check_password_hash 都是werkzeug.security下的方法。
因为两个魔力函数的存在,使得,
涉及密码时不可以传统的方式验证用户是否存在:
python
def find_user():
with app.app_context():
# 上面一种查询方式错误,因为对password的属性进行了getter和setter的装饰器修饰
# User.query.filter_by(email=email, password=password).first()
# 正确的方式应用这样
# user = User.query.filter_by(_password="123456").first()
# 业务上的使用方式是这样:
param = {
"email": "a@qq.com",
"password": "123456"
}
user = User.query.filter_by(email=param["email"]).first()
if user:
print(user.check_password(param["password"]))
print(user)
a_en = generate_password_hash("a")
print(check_password_hash(a_en, "a"))
print(a_en)
filter的妙用
python
@property
def intro(self):
self.intro = filter(lambda x: True if x else False, [self.author, self.publisher, self.price])