Flask项目基本拆分

Flask项目基本拆分

96

垃圾桶边的狗 关注

用到的知识点

Flask四大内置对象

  • request
  • session
  • g
  • app (config)

提升代码复用性

  • 封装函数
  • 装饰器
  • 类继承
  • 钩子函数

钩子函数

  • 中间件一个东西
  • 面向切面编程的切点
- before_request
    Django :process_reqeust
after_request
     Django : process_response
- errorhandler
     Django : processs_exception

插件使用

  • 寻找适合的插件
  • 安装插件
  • 初始化插件
  • 操作插件

工作环境

  • 开发环境
  • 开发工程师使用
  • 测试环境
  • 测试工程师使用
  • 演示环境
  • 给项目经理看
  • 演习使用
  • 线上环境(生产环境)
  • 真实用户使用的环境

流程图

[图片上传失败...(image-8d9a8b-1544252761684)]

项目目录

[图片上传失败...(image-a84813-1544252761684)]

App/init.py
from flask import Flask

from App.extension import init_ext
from App.middleware import load_middleware
from App.settings import envs
from App.views import init_blue

def create_app(env):
    app = Flask(__name__)

    # 初始化App的配置
    app.config.from_object(envs.get(env))

    # 初始化第三方的插件
    init_ext(app=app)

    # 加载中间件
    load_middleware(app=app)

    # 初始化路由系统
    init_blue(app=app)

    return app

App/manage.py
import os

from flask_migrate import MigrateCommand
from flask_script import Manager

from App import create_app

env = os.environ.get("FLASK_PROJECT", "product")

app = create_app(env)

manager = Manager(app=app)
manager.add_command("db", MigrateCommand)

if __name__ == '__main__':
    manager.run()

App/extension.py
from flask_caching import Cache
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
migrate = Migrate()
cache = Cache(config={
    "CACHE_TYPE": "redis"
})

def init_ext(app):
    db.init_app(app=app)
    migrate.init_app(app=app, db=db)
    cache.init_app(app)

App/settings.py
知识点:

对不同的环境进行分离

def get_db_uri(dbinfo):

    engine = dbinfo.get("ENGINE")
    driver = dbinfo.get("DRIVER")
    user = dbinfo.get("USER")
    password = dbinfo.get("PASSWORD")
    host = dbinfo.get("HOST")
    port = dbinfo.get("PORT")
    name = dbinfo.get("NAME")

    return "{}+{}://{}:{}@{}:{}/{}".format(engine, driver,user, password, host, port, name)

class Config:

    DEBUG = False

    TESTING = False

    SECRET_KEY = "wertyuiodfghjkl!@#$%^&I(*&^5"

    SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopConfig(Config):

    DEBUG = True

    dbinfo = {
        "ENGINE": "mysql",
        "DRIVER": "pymysql",
        "USER": "root",
        "PASSWORD": "123456",
        "HOST": "localhost",
        "PORT": "3306",
        "NAME": "FlaskProject1"
    }

    SQLALCHEMY_DATABASE_URI = get_db_uri(dbinfo)

class TestingConfig(Config):

    TESTING = True

class StagingConfig(Config):

    pass

class ProductConfig(Config):

    pass

envs = {
    "develop": DevelopConfig,
    "testing": TestingConfig,
    "staging": StagingConfig,
    "product": ProductConfig,
    "default": DevelopConfig,
}

App/models/init.py
from .sutdent_model import Student
from .teacher_model import Teacher

App/models/student_model.py
知识点:

1.用户密码加密
2.用户密码校验
4.数据自动保存数据库
5.用户权限校验

from werkzeug.security import generate_password_hash, check_password_hash

from App.extension import db

PERMISSION_STUDENT_LEARN = 1
PERMISSION_STUDENT_MANAGE = 2
PERMISSION_STUDENT_USE_PHONE = 4

class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    s_name = db.Column(db.String(16), unique=True)
    _s_password = db.Column(db.String(256))
    s_permission = db.Column(db.Integer, default=PERMISSION_STUDENT_LEARN)

    @property
    def s_password(self):
        raise Exception("can't access")

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

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

    def check_permission(self, permission):
        return self.s_permission & permission == permission

    def save(self):
        try:
            db.session.add(self)
            db.session.commit()
        except Exception as e:
            print(e)
            return False
        else:
            return True

App/views/init.py
from App.views.book_blue import book_blue
from App.views.first_blue import blue
from App.views.student_blue import blue_student

def init_blue(app):
    app.register_blueprint(blueprint=blue)
    app.register_blueprint(blueprint=blue_student)
    app.register_blueprint(blueprint=book_blue)

App/views/login_register.py
>知识点:

uuid生成token唯一值
缓存:对token进行过期时间设置
abort

import uuid

from flask import Blueprint, request, abort, jsonify

from App.extension import cache
from App.models import Student

blue_student = Blueprint("blue_student", __name__, url_prefix='/students')

@blue_student.route("/", methods=["POST", ])
def students():
    action = request.args.get("action")

    username = request.form.get("username")
    password = request.form.get("password")

    if action == "register":

        student = Student()
        student.s_name = username
        student.s_password = password

        if not student.save():
            abort(401)
        return "注册成功"

    elif action == "login":

        # Student.query.filter(Student.s_name.__eq__(username))
        student_list = Student.query.filter(Student.s_name == (username)).all()
        if not student_list:
            abort(404)
        student = student_list[0]

        if not student.verify_password(password):
            abort(401)

        token = uuid.uuid4().hex

        cache.set(token, student.id, timeout=60*60*24)

        data = {
            "msg": "登录成功",
            "token": token
        }

        return jsonify(data)

    else:
        abort(400)

App/views/permission_book.py
知识点

Flask内置对象:g

from flask import Blueprint, request, g

from App.extension import cache
from App.models import Student
from App.models.sutdent_model import PERMISSION_STUDENT_LEARN, PERMISSION_STUDENT_MANAGE

book_blue = Blueprint("book_blue", __name__, url_prefix="/books")

@book_blue.route("/")
def books():

    student = g.user

    if not student.check_permission(PERMISSION_STUDENT_MANAGE):
        return "没有访问本书的权限"

    return "这是你喜欢的书<<算法导论>>,请拿走"

App/middleware.py

知识点:

面向切面编程
中间件
两个概念:切点和切面
切点:可以在那切开
切面:从切点处切开能获得什么
flask内置对象:g
g:可以跨函数使用,将数据传到App/views/permission_book.py
缓存
token

from flask import request, g

from App.extension import cache
from App.models import Student

require_login_list = ["/books/",]

def load_middleware(app):

    @app.before_request
    def before_request():
        path = request.path
        if path in require_login_list:
            token = request.args.get("token")

            if not token:
                return "token 不存在"

            student_id = cache.get(token)

            if not student_id:
                return "id 已过期"

            student = Student.query.get(student_id)

            if not student:
                return "student 已消失"

            g.user = student
            g.auth = token

你可能感兴趣的:(Flask项目基本拆分)