Flask教程--第一个Flask应用:蓝图和视图

左丘照
2023-12-01

什么是蓝图

蓝图,官方文档的解释——“A Blueprint is a way to organize a group of related views and other code.”(蓝图是一种组织一组视图及其它代码的方式),说得比较抽象,不容易理解。具体一些来说就是对代码进行模块化管理(或者说分类管理),可以和Django框架做对比:

1.Django首先创建的是一个项目(project), 项目里面包含各个子模块称为应用(application)。

2.Flask首先创建的是一个应用(application), 应用包含各个子模块称为蓝图(blueprint)。

蓝图的基本用法

1.创建蓝图并注册到应用

flaskr/auth.py

创建蓝图实例:

# -*- coding:utf-8 -*-
"""蓝图与视图

"""

from flask import Blueprint  # 导入蓝图
bp = Blueprint('auth', __name__)  # 创建蓝图实例

flaskr/__init__.py

把蓝图注册到应用:

# 注册蓝图
        from . import auth
    app.register_blueprint(auth.bp)

2.使用蓝图创建路由

flaskr/auth.py

这里使用蓝图创建了三个路由:注册,登陆以及退出。

# -*- coding:utf-8 -*-
"""认证蓝图

"""

import functools
from flask import Blueprint, flash, g, redirect, render_template, request, session, url_for
from werkzeug.security import check_password_hash, generate_password_hash
from flaskr.db import get_db

# auth:蓝图名字,__name__:指定蓝图定义的位置,url_prefix:添加到所有与蓝图相关的url前面
bp = Blueprint('auth', __name__, url_prefix='/auth')


@bp.route('/register', methods=['GET', 'POST'])
def register():
    """用户注册

    """
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        error = None
        if not username:
            error = '用户名不能为空'
        elif not password:
            error = '密码不能为空'
        elif db.execute('SELECT id FROM user WHERE username = ?', (username,)
                        ).fetchone() is not None:
            error = '用户名 {} 已经被注册'.format(username)
        if error is None:
            db.execute('INSERT INTO user(username, password) VALUES(?, ?)',
                       (username, generate_password_hash(password)))
            db.commit()
            return redirect(url_for('auth.login'))  # 注册成功跳转到登陆界面
        flash(error)
    return render_template('')


@bp.route('login', methods=['GET', 'POST'])
def login():
    """用户登陆

    """
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = get_db()
        error = None
        # 在前端设置用户名和密码必填,否则无法提交
        user = db.execute('SELECT * FROM user WHERE username=?', username).fetchone()
        if user is None:
            error = '用户名不存在'
        elif not check_password_hash(user['username'], username):
            error = '密码错误'
        if error is None:
            session.clear()
            session['user_id'] = user['id']
            return redirect(url_for('index'))
        flash(error)
    return render_template('auth/login.html')


@bp.before_app_request  # 该函数在视图函数之前执行,无论是客户端发起还是服务端发起的请求
def load_logged_in_user():
    user_id = session.get('user_id')
    if user_id is None:
        g.user = None
    else:
        g.user = get_db().execute('SELECT * FROM user WHERE id=?', (user_id,)).fetchone()


@bp.route('/logout')
def logout():
    """退出:清除所有session, 返回到首页

    """
    session.clear()
    return redirect(url_for('index'))


def login_required(view):
    """
    
    """
    @functools.wraps(view)
    def wrap_view(**kwargs):
        if g.user is None:
            return redirect(url_for('auth.login'))
        return view(**kwargs)

    return wrap_view

参考资料

[1]Flask Blue Prints and Views:https://flask.palletsprojects.com/en/1.1.x/tutorial/views/

[2]理解Flask的BluePrint:子模块和框架糖, https://lvxiaoyu.com/static/posts/20170613.3.html#blue_all

 类似资料: