Flask教程--第一個Flask應用:藍圖和視圖

什麼是藍圖

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章