Flask自帶的經常使用組件介紹


Flask的優勢是靈活小巧,三行代碼便可運行一個web服務器,但基於Flask構建的功能並不比Django弱,關鍵就就是除了flask自帶的基礎功能外,還有豐富的組件進行支持,本文先對經常使用的自帶組件進行簡單的介紹。測試的Flask版本是0.12。

在構建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應用的主類,在源碼分析中提到,再也不贅述。這裏給一個Flask應用的經典樣例,請務必注意下面的代碼都是在此樣例基礎上進行拓展的python

#示例-1
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()

render_template

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

session

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}這個數據。

數組

url_for

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

redirect

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中,咱們能夠將一些用戶可能會訪問的連接重定向到博客主頁上。

flash

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 %}

make_response

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你能夠個性化定製返回的響應對象。

jsonify

對於數據進行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

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')

request

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

abort是Flask中Abort類的一個實例,一般採用abort(error_code)的方式進行調用。abort的狀態碼最好是本身實現的錯誤定義,如示例-11所示。

g

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

send_from_directory

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_filestream_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)

Markup

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標籤轉移成顯示

current_app

應用上下文對象,官方文檔有詳細的介紹,

相關文章
相關標籤/搜索