咱們學習Flask框架,是從寫單個文件,執行hello world開始的。咱們在這單個文件中能夠定義路由、視圖函數、定義模型等等。但這顯然存在一個問題:隨着業務代碼的增長,將全部代碼都放在單個程序文件中,是很是不合適的。這不只會讓代碼閱讀變得困難,並且會給後期維護帶來麻煩。html
以下示例:咱們在一個文件中寫入多個路由,這會使代碼維護變得困難。python
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中的模塊製做和導入就是基於實現功能模塊的封裝的需求。mysql
嘗試用模塊導入的方式解決: 咱們把上述一個py文件的多個路由視圖函數給拆成兩個文件:app.py和admin.py文件。app.py文件做爲程序啓動文件,由於admin文件沒有應用程序實例app,在admin文件中要使用app.route路由裝飾器,須要把app.py文件的app導入到admin.py文件中。sql
# 文件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中的模塊化雖然能把代碼給拆分開,但不能解決路由映射的問題。數據庫
藍圖:用於實現單個應用的視圖、模板、靜態文件的集合。flask
藍圖就是模塊化處理的類。session
簡單來講,藍圖就是一個存儲操做路由映射方法的容器,主要用來實現客戶端請求和URL相互關聯的功能。 在Flask中,使用藍圖能夠幫助咱們實現模塊化應用的功能。app
藍圖是保存了一組未來能夠在應用對象上執行的操做。註冊路由就是一種操做,當在程序實例上調用route裝飾器註冊路由時,這個操做將修改對象的url_map路由映射列表。當咱們在藍圖對象上調用route裝飾器註冊路由時,它只是在內部的一個延遲操做記錄列表defered_functions中添加了一個項。當執行應用對象的 register_blueprint() 方法時,應用對象從藍圖對象的 defered_functions 列表中取出每一項,即調用應用對象的 add_url_rule() 方法,這將會修改程序實例的路由映射列表。框架
1、建立藍圖對象。模塊化
#Blueprint必須指定兩個參數,admin表示藍圖的名稱,__name__表示藍圖所在模塊 admin = Blueprint('admin',__name__)
2、註冊藍圖路由。
@admin.route('/') def admin_index(): return 'admin_index'
3、在程序實例中註冊該藍圖。
app.register_blueprint(admin,url_prefix='/admin')
from flask import Flask #導入藍圖對象 from login import logins from user import users app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' #註冊藍圖,第一個參數logins是藍圖對象,url_prefix參數默認值是根路由,若是指定,會在藍圖註冊的路由url中添加前綴。 app.register_blueprint(logins,url_prefix='') app.register_blueprint(users,url_prefix='') if __name__ == '__main__': app.run(debug=True)
from flask import Blueprint,render_template #建立藍圖,第一個參數指定了藍圖的名字。 users = Blueprint('user',__name__) @users.route('/user') def user(): return render_template('user.html')
from flask import Blueprint,render_template #建立藍圖 logins = Blueprint('login',__name__) @logins.route('/login') def login(): return render_template('login.html')
文件目錄: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_bk app = 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.name class 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.data wtf_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_map app.run(debug=True)