什麼是藍圖
藍圖,官方文檔的解釋——“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