Web框架——Flask系列之蓝图Blueprint(二十一)
一、為什么學習藍圖?
我們學習Flask框架,是從寫單個文件,執行hello world開始的。我們在這單個文件中可以定義路由、視圖函數、定義模型等等。但這顯然存在一個問題:隨著業務代碼的增加,將所有代碼都放在單個程序文件中,是非常不合適的。這不僅會讓代碼閱讀變得困難,而且會給后期維護帶來麻煩。
如下示例:我們在一個文件中寫入多個路由,這會使代碼維護變得困難。
from flask import Flask app = Flask(__name__) @app.route('/')def index():return 'index'@app.route('/list')def list():return 'list'@app.route('/detail')def detail():return 'detail'@app.route('/')def admin_home():return 'admin_home'@app.route('/new')def new():return 'new'@app.route('/edit')def edit():return 'edit'問題:一個程序執行文件中,功能代碼過多。就是讓代碼模塊化。根據具體不同功能模塊的實現,劃分成不同的分類,降低各功能模塊之間的耦合度。python中的模塊制作和導入就是基于實現功能模塊的封裝的需求。
嘗試用模塊導入的方式解決: 我們把上述一個py文件的多個路由視圖函數給拆成兩個文件:app.py和admin.py文件。app.py文件作為程序啟動文件,因為admin文件沒有應用程序實例app,在admin文件中要使用app.route路由裝飾器,需要把app.py文件的app導入到admin.py文件中。
# 文件app.py from flask import Flask # 導入admin中的內容 from admin import * app = Flask(__name__)@app.route('/') def index():return 'index'@app.route('/list') def list():return 'list'@app.route('/detail') def detail():return 'detail'if __name__ == '__main__':app.run() # 文件admin.py from app import app @app.route('/') def admin_home():return 'admin_home'@app.route('/new') def new():return 'new'@app.route('/edit') def edit():return 'edit'啟動app.py文件后,我們發現admin.py文件中的路由都無法訪問。 也就是說,python中的模塊化雖然能把代碼給拆分開,但不能解決路由映射的問題。
二、什么是藍圖?
藍圖:用于實現單個應用的視圖、模板、靜態文件的集合。
藍圖就是模塊化處理的類。
簡單來說,藍圖就是一個存儲操作路由映射方法的容器,主要用來實現客戶端請求和URL相互關聯的功能。 在Flask中,使用藍圖可以幫助我們實現模塊化應用的功能。
三、藍圖的運行機制:
藍圖是保存了一組將來可以在應用對象上執行的操作。注冊路由就是一種操作,當在程序實例上調用route裝飾器注冊路由時,這個操作將修改對象的url_map路由映射列表。當我們在藍圖對象上調用route裝飾器注冊路由時,它只是在內部的一個延遲操作記錄列表defered_functions中添加了一個項。當執行應用對象的 register_blueprint() 方法時,應用對象從藍圖對象的 defered_functions 列表中取出每一項,即調用應用對象的 add_url_rule() 方法,這將會修改程序實例的路由映射列表。
四、藍圖的使用:
文件目錄:
程序執行文件/test4/test.py
創建藍圖:/test4/user.py
from flask import Blueprint,render_template #創建藍圖,第一個參數指定了藍圖的名字。 users = Blueprint('user',__name__)@users.route('/user') def user():return render_template('user.html')創建藍圖:/test4/login.py
from flask import Blueprint,render_template #創建藍圖 logins = Blueprint('login',__name__)@logins.route('/login') def login():return render_template('login.html')運行/test4/test.py文件
五、動態路由示例(作者–圖書):
文件目錄:Flask_test4/delete.py
from flask import Blueprint,redirect,url_for app_au = Blueprint('app_au',__name__) app_bk = Blueprint('app_bk',__name__)from test4 import *@app_au.route('/delete_au<id>') def delete_au(id):del_au = Author.query.filter_by(id=id).first()db.session.delete(del_au)db.session.commit()return redirect(url_for('index'))@app_bk.route('/delete_bk<id>') def delete_bk(id):del_bk = Book.query.filter_by(id=id).first()db.session.delete(del_bk)db.session.commit()return redirect(url_for('index'))文件目錄:Flask_test4/test4.py
#coding=utf-8 #目的:創建兩個模型類型,實現數據庫的連接和數據的操作 from flask import Flask,render_template,request,redirect,url_for from flask_sqlalchemy import SQLAlchemy from flask_wtf import FlaskForm from wtforms import StringField,SubmitField from wtforms.validators import DataRequired #導入delete文件中的藍圖對象 from delete import app_au,app_bkapp = Flask(__name__) #對數據庫連接的基本設置 app.config['SQLALCHEMY_DATABASE_URI']='mysql://root:mysql@localhost/test0' app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True #把應用程序的實例和SQLAlchemy進行關聯 db = SQLAlchemy(app) app.config['SECRET_KEY'] = 'a'#自定義表單,實現數據的輸入保存操作 class Append(FlaskForm):author = StringField(validators=[DataRequired()])book = StringField(validators=[DataRequired()])submit = SubmitField(u'提交')#自定義模型類 class Author(db.Model):__tablename__ = 'authors'id = db.Column(db.Integer,primary_key=True)name = db.Column(db.String(32),unique=True)def __repr__(self):return 'author:%s'%self.nameclass Book(db.Model):__tablename__ = 'books'id = db.Column(db.Integer,primary_key=True)info = db.Column(db.String(32),unique=True)def __repr__(self):return 'book:%s'%self.info@app.route('/',methods=['GET','POST']) def index():au = Author.query.all()bk = Book.query.all()form = Append()if form.validate_on_submit():#從表單中獲取數據wtf_au = form.author.datawtf_bk = form.book.data#把數據存入模型類中db_au = Author(name=wtf_au)db_bk = Book(info=wtf_bk)#添加到數據庫操作db.session.add_all([db_au,db_bk])db.session.commit()au = Author.query.all()bk = Book.query.all()return render_template('index.html',au=au,bk=bk,form=form)if request.method == 'GET':return render_template('index.html',au=au,bk=bk,form=form)#注冊藍圖 app.register_blueprint(app_au) app.register_blueprint(app_bk)if __name__ == '__main__': print app.url_mapapp.run(debug=True)查看藍圖路由:藍圖路由可以分為兩塊,".“前面的是藍圖名稱,”."后面的是視圖函數名。
總結
以上是生活随笔為你收集整理的Web框架——Flask系列之蓝图Blueprint(二十一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 四、MySQL分页查询 + 子查询复习
- 下一篇: 搞懂语音去噪