在構建Flask應用導入的時候,一般是from flask import Flask
的方式開始的,說明flask這個python package裏面應該還藏了很多好東西,從源碼來看看:html
from werkzeug.exceptions import abort from werkzeug.utils import redirect from jinja2 import Markup, escape from .app import Flask, Request, Response from .config import Config from .helpers import url_for, flash, send_file, send_from_directory, \ get_flashed_messages, get_template_attribute, make_response, safe_join, \ stream_with_context from .globals import current_app, g, request, session, _request_ctx_stack, \ _app_ctx_stack from .ctx import has_request_context, has_app_context, \ after_this_request, copy_current_request_context from .blueprints import Blueprint from .templating import render_template, render_template_string # the signals from .signals import signals_available, template_rendered, request_started, \ request_finished, got_request_exception, request_tearing_down, \ appcontext_tearing_down, appcontext_pushed, \ appcontext_popped, message_flashed, before_render_template # We're not exposing the actual json module but a convenient wrapper around # it. from . import json # This was the only thing that Flask used to export at one point and it had # a more generic name. jsonify = json.jsonify # backwards compat, goes away in 1.0 from .sessions import SecureCookieSession as Session json_available = True
Flask自帶組件基本上都在這裏了,咱們一一來分析這些組件的功能及基本的用法。前端
Flask應用的主類,在源碼分析中提到,再也不贅述。這裏給一個Flask應用的經典樣例,請務必注意下面的代碼都是在此樣例基礎上進行拓展的。python
#示例-1 from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run()
def render_template(template_name_or_list, **context)web
template_name_or_list參數是模板名稱,context參數接受模板中已經定義的變量值。
Jinja是Flask的模板引擎,提供對HTML頁面的數據渲染,render_template是Flask中調用template目錄的html模板並渲染數據。代碼示例:ajax
#示例-2 from flask import render_template @app.route("/") def index(): name="He Kejun" return render_template("index.html",name=name)
上述的代碼中調用了/template/index.html
模板,並將「name: He Kejun」這一數據渲染進該模板其能夠直接經過Hello, {{name}}
的方式顯示‘Hello, He Kejun'json
flask的session機制,Flask從服務器經過瀏覽器的cookie保存信息,該信息經過應用的祕鑰進行加密確保數據安全。session在用戶身份認證和數據共享提供較好的幫助。樣例:flask
#示例-3 from flask import session app.config["SECRET_KEY"]="YOU CAN NOT GUESS ME" #加密的祕鑰,建議放在配置文件中 @app.route("/") def index(): session["name"]="kejun" return "hello,world" @app.route("/name") def name(): return session["name"]
首先訪問http://127.0.0.1:5000 生成用戶名,查看瀏覽器的cookie能夠看到session已經寫入了,這時候再訪問http://127.0.0.1:5000/name就能夠看到名字了,在兩個HTTP請求之間共享了{name: kejun}
這個數據。
數組
def url_for(endpoint, **values):瀏覽器
根據已經定義好的view函數來建立URL到指定的endpoint,Flask的endpoint能夠理解爲Restful框架中資源。輸入的endpoint是函數名,values是關鍵字參數,每一個關鍵字參數對應URL規則的變量部分,未知變量部分被插入到URL中做查詢參數,具體的樣例,我使用了官網的樣例安全
#示例-4 from flask import url_for @app.route("/") def index(): pass @app.route("/login") def login(): pass @app.route("/user/<username>") def profile(username):pass with app.test_request_context(): print(url_for("index)) #/ print(url_for("login")) #/login print(url_for("login",next="/")) #/login?next=/ print(url_for("profile,username="kejun")) @/user/kejun
def redirect(location, code=302, Response=None):
參數location是跳轉的目標位置,code是HTTP響應碼默認是302(臨時移動),也能夠設置爲301(永久移動,即所請求的文檔在別處),303(參見其餘信息),305(使用代理),不能夠是300(多重選擇),304(未修正更新)。
redirect的做用是重定向,設置響應並跳轉到指定的位置。在Flask中一般與url_for這個功能一塊兒使用。應用實例:
#示例-5 from flask import redirect @app.route("/") @app.route("/index") def index(): return redirect(url_for("blog")) @app.route("/blog") def blog(): pass
在示例-5中,咱們能夠將一些用戶可能會訪問的連接重定向到博客主頁上。
def flash(message, category='message'):
參數message是消息內容,category是消息類型,方便前端過濾。
Web設計中提供用戶的友好性是及時將反饋提供給用戶。消息閃現Flash提供了一個很是簡單的機制。
#示例-6-1 from flask import flash def print_message(): flash("This is a message","message") return "Message Page" def print_error() flash("This is a error","error") return "Error Page"
在前端,咱們能夠這樣定義HTML頁面從而顯示內容
#示例-6-2 {% with msgs = get_flashed_messages(category_filter=["message"]) %} {% if msgs %} {% for msg in msgs %} <p>{{msg}}</p> {% endfor %} {% endif %} {% endwith %} {% with errors= get_flashed_messages(category_filter=["error"]) %} {% iferrors%} {% for errorinerrors%} <p>{{error}}</p> {% endfor %} {% endif %} {% endwith %}
def make_response(*args):
Flask會自動將view函數返回的值轉換成響應對象,除此以外,你能夠經過調用make_response來生成可定製的響應對象,包括設置cookie,session等等,更多的使用方法能夠參見教程
#示例-7 from flask import make_response def index(): return render_template('index.html', foo=42) def index(): response = make_response(render_template('index.html', foo=42)) resp.set_cookie("am_i_handsome","yes") #設置cookie return response
在上述的示例中,經過make_response,還能夠定製cookie。也就是說,經過make_response你能夠個性化定製返回的響應對象。
對於數據進行json轉化,應用於經過ajax方式訪問時須要返回json數據。
#示例-8 from flask importjsonify @app.route("/update_user_name",methods=['GET', 'POST']) def update_user_name(): ip=request.headers.get('X-Real-Ip', request.remote_addr) user_name=request.args.get('new_user_name',"",type=str) if user_name: if set_user_name(ip,user_name): return jsonify(return_code="1") return jsonify(return_code="0")
blueprint藍圖是flask自帶的一種拓展已有應用結構的方式,這是Flask在中大型Web應用中的一種框架設計。藍圖把把功能相似或者同一模塊下的視圖函數組合在一塊兒,基於藍圖,咱們能夠把Flask應用拆分紅不一樣的組件。每一個藍圖均可以自定義本身的模板文件目錄和靜態目錄。定義好的藍圖目錄能夠經過註冊的方式加入Flask應用中。代碼示例以下:
#示例-9-1 from flask import Blueprint example=Blueprint('example',__name__,template_folder='templates/example',static_folder='static/example',url_prefix='/example') #藍圖example下的視圖函數 @example.route def index(): return render_template("index.html")
一個藍圖就是一個模塊,上述的example藍圖建立好後,須要註冊到Flask應用中,樣例代碼以下:
示例-9-2 from flask import Flask from yourapplication.examples import example app = Flask(__name__) app.register_blueprint(example)
本文以前介紹了url_for的使用方法,在藍圖中使用url_for定位視圖函數須要增長藍圖名稱,如定位到上述index視圖函數url_for('example.index')
Flask構建了一個與請求相關的全局變量,在全部的視圖函數及模板中均可以訪問該對象。應用示例以下:
#示例-10 from flask import request def get_user_ip(): ip=request.headers.get('X-Real-Ip', request.remote_addr) return "Request ip address is {0}".format(ip)
abort是Flask中Abort類的一個實例,一般採用abort(error_code)
的方式進行調用。abort的狀態碼最好是本身實現的錯誤定義,如示例-11所示。
Flask中的全局變量g,能夠爲特定請求臨時存儲任何須要的數據而且是線程安全的,當請求結束時,這個對象會被銷燬,下一個新的請求到來時又會產升一個新的g。
#示例-11 from flask import g,session,abort,render_template @app.before_request def before_request(): if 'user_name' in session: g.user=User.query.get(session['user_name']) @app.route('/admin') def admin(): if g.user is None: abort(404) return render_template('admin.html') @app.errorhandler(404): def page_not_found(): return render_template("404.html"),404
def send_from_directory(directory, filename, **options):
參數directory是文件所在目錄,filename是文件名稱,options參數是send_file的傳入參數,options可選的參數包括 mimetype、as_attachment、attachment_filename、add_etags、cache_timeout、conditional。
send_from_directory能夠認爲send_file上加了一層殼子,判斷了文件路徑及文件名,而後交由send_file處理,實際上將文件內容發給瀏覽器,因此它一個重要的應用場景是支持文件下載。
對於文件下載,媒體數據流傳輸的能夠再研究一下send_file
和stream_with_context
這兩個功能,也很是好用。
示例代碼爲:
#示例-11 from flask import send_from_directory @app.route('/getfile', methods=['GET']) def download_file(): return send_from_directory(r"D:\Workspace\flask_source", "aa.txt", as_attachment=True)
class Markup(text_type):
將輸入文本text_type標記爲安全,不須要進行轉移。
若是將HTML做爲變量經過Jinjia模板的方式做爲變量插入頁面中,Flask會自動嘗試對HTML進行轉義。這是必要的安全措施,確保惡意用戶經過提交一段惡意代碼並顯示在頁面中,從而讓其餘用戶的瀏覽器進行執行。Flask同時提供兩種方法來對安全的HTML不轉義直接顯示:一個是利用Markup類,二是利用Jinjia關鍵字safe
。示例代碼爲:
示例-12 from flask import Markup @app.route("/") def index(): return Markup('Hello %s!') % '<strong>kejun</strong>'#顯示strong標籤 @app.route("/1") def index1(): return 'Hello %s!' % '<strong>kejun</strong>'#將strong標籤轉移成顯示
應用上下文對象,官方文檔有詳細的介紹,