Flask web模板四–添加数据库模块

通过flask-sqlalchemy来实现flask操作数据库,这里创建一个user模型来实现将用户信息保存到mysql

1、安装flask_sqlalchemy

pip install flask-sqlalchemy

2、创建一个模型的基类
在app/models目录下创建base.py,内容如下

# -*- coding:utf-8 -*-
# 使用flask封装的sqlalchemy需要从flask_sqlalchemy导入
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from sqlalchemy import Column, Integer, SmallInteger, String
from contextlib import contextmanager
from datetime import datetime


# 定义一个SQLAlchemy子类,添加try 代码,后面调用数据库提交函数时可以使用with语句
class SQLAlchemy(_SQLAlchemy):
    @contextmanager
    def auto_commit(self):
        try:
            yield
            self.session.commit()
        except Exception as e:
            db.session.rollback()
            raise e


db = SQLAlchemy()


# 创建一个基类模型,让其他模型都继承这个基类模型
# 基类型模型是所有模型都共有的一些属性
class Base(db.Model):
    __abstract__ = True  # Base是一个基类,这样就不会去创建这个表
    add_time = Column('add_time', Integer)
    status = Column(SmallInteger, default=1)

    # 为create_time 自动生成默认值
    def __init__(self):
        self.add_time = int(datetime.now().timestamp())

    # 如果传入的参数是模型中包含的对象,则进行赋值
    def set_attrs(self, attrs_dict):
        for key, value in attrs_dict.items():
            # 判断当前这个对象是否包含名字叫key 的属性
            if hasattr(self, key) and key != 'id':
                setattr(self, key, value)

    def delete(self):
        self.status = 0

    # 创建一个属性方法,如果模型包含create_time属性则被时间戳格式时间转换为字符串
    @property
    def add_datetime(self):
        if self.add_time:
            return datetime.fromtimestamp(self.add_time)
        else:
            return None

    # 为所有模型添加一个状态删除的方法,状态0表示删除
    def delete(self):
        self.status = 0

3、创建一个User模型继承Base模型
在models目录下创建user.py,内容如下

# -*- coding:utf-8 -*-

# 导入sqlalchemy的基本类型可以从sqlalchemy基础包中导入
from sqlalchemy import Column, Integer, String, Boolean, Float
from app.models.base import Base, db
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
# from app import login_manager
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from flask import current_app
from math import floor


# from app.libs.enums import PendingStatus


# 用户模型,让用户继承flask_login中的UserMixin 可以使用cookie的相关功能
class User(UserMixin, Base):
    id = Column(Integer, primary_key=True)
    nickname = Column(String(24), nullable=False)
    phone_number = Column(String(18), unique=True)
    # 这里的_passowrd 是模型中的名字,而在数据库中的字段是password
    # 目的是为了在使用基类中的set_attr 方法写入密码的值时不自动写入明文
    _password = Column('password', String(128))
    email = Column(String(50), unique=True, nullable=False)
    confirmed = Column(Boolean, default=False)

    # 获取密码
    @property
    def password(self):
        return self._password

    # 修改密码,在密码入库时进行加密,raw 表示一个明文的密码
    @password.setter
    def password(self, raw):
        self._password = generate_password_hash(raw)

    # 验证密码,传入明文密码
    def check_password(self, raw):
        # 使用check_password_hash函数对明文密码加密后再与数据库中的密文进行比较
        return check_password_hash(self._password, raw)

    @staticmethod
    def reset_password(token, new_password):
        s = Serializer(current_app.config['SECRET_KEY'])
        # 读取token中的用户id
        try:
            data = s.loads(token.encode('utf-8'))
        except:
            return False
        uid = data.get('id')
        with db.auto_commit():
            user = User.query.get(uid)
            user.password = new_password
        return True

    # 用户登录后修改密码
    def change_password(self, new_password):
        self._password = generate_password_hash(new_password)

    def generate_token(self, expiration=600):
        # 传入一个随机加密串
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        # 传入一个包含用户IDE字典
        return s.dumps({'id': self.id}).decode('utf-8')

    # 定义一个函数获取当前用户的一个简历
    @property
    def summary(self):
        return dict(
            nickname=self.nickname,
            email=self.email
        )

# # 这个函数是独立的模块函数,不是User模型的方法
# # 加上装饰器是让login_manager这个插件加载这个函数,在其他视图函数中可以调用这个函数
# @login_manager.user_loader
# def get_user(uid):
#     # 通过用户的id 来查询用户的模型,uid是主键查询可以不用filer_by可用get
#     return User.query.get(int(uid))

4、在app/__init__.py中初始化sqlalchemy插件,并初始化数据库

# -*- coding:utf-8 -*-
# 初始化flask核心对象

from flask import Flask
from app.models.base import db
from app.models.user import User


# 定义一个函数用来创建app核心对象
def create_app():
    app = Flask(__name__)
    # app.config.from_object('config')
    app.config.from_object('app.secure')
    app.config.from_object('app.setting')
    # 调用注册蓝图
    register_blueprint(app)
    # 初始化数据库
    db.init_app(app)
    with app.app_context():
        # 调用生成mysql表的函数
        db.create_all()
    return app


#  创建注册蓝图的方法
def register_blueprint(app):
    # 导入蓝图对象
    from app.web.blueprint import web
    app.register_blueprint(web)

5、在app/secure.py中添加数据库连接配置

# -*- coding:utf-8 -*-
# 定义项目机密信息配置文件,开发环境和生产环境不同,不能上传git


DEBUG = True

# flask连接数据库
SQLALCHEMY_DATABASE_URI = 'mysql+cymysql://server:server@localhost:3306/server'
SQLALCHEMY_TRACK_MODIFICATIONS = True

# 密码
SECRET_KEY = 'password'

6、在mysql数据库中创建server数据库,并授予权限,通过pycharm运行run.py启动项目可以创建user表。

发表评论