【python】Flask视图
2.1 從 Hello World 開(kāi)始
Flask程序運(yùn)行過(guò)程:
所有Flask程序必須有一個(gè)程序?qū)嵗?/p>
Flask調(diào)用視圖函數(shù)后,會(huì)將視圖函數(shù)的返回值作為響應(yīng)的內(nèi)容,返回給客戶端。一般情況下,響應(yīng)內(nèi)容主要是字符串和狀態(tài)碼。
當(dāng)客戶端想要獲取資源時(shí),一般會(huì)通過(guò)瀏覽器發(fā)起HTTP請(qǐng)求。此時(shí),Web服務(wù)器使用WSGI(Web Server Gateway Interface)協(xié)議,把來(lái)自客戶端的所有請(qǐng)求都交給Flask程序?qū)嵗SGI是為 Python 語(yǔ)言定義的Web服務(wù)器和Web應(yīng)用程序之間的一種簡(jiǎn)單而通用的接口,它封裝了接受HTTP請(qǐng)求、解析HTTP請(qǐng)求、發(fā)送HTTP,響應(yīng)等等的這些底層的代碼和操作,使開(kāi)發(fā)者可以高效的編寫(xiě)Web應(yīng)用。
程序?qū)嵗褂肳erkzeug來(lái)做路由分發(fā)(URL請(qǐng)求和視圖函數(shù)之間的對(duì)應(yīng)關(guān)系)。根據(jù)每個(gè)URL請(qǐng)求,找到具體的視圖函數(shù)。 在Flask程序中,路由的實(shí)現(xiàn)一般是通過(guò)程序?qū)嵗膔oute裝飾器實(shí)現(xiàn)。route裝飾器內(nèi)部會(huì)調(diào)用add_url_route()方法實(shí)現(xiàn)路由注冊(cè)。
調(diào)用視圖函數(shù),獲取響應(yīng)數(shù)據(jù)后,把數(shù)據(jù)傳入HTML模板文件中,模板引擎負(fù)責(zé)渲染響應(yīng)數(shù)據(jù),然后由Flask返回響應(yīng)數(shù)據(jù)給瀏覽器,最后瀏覽器處理返回的結(jié)果顯示給客戶端。
示例:
新建文件hello.py:
# 導(dǎo)入Flask類 from flask import Flask#Flask類接收一個(gè)參數(shù)__name__ app = Flask(__name__)# 裝飾器的作用是將路由映射到視圖函數(shù)index @app.route('/') def index():return 'Hello World'# Flask應(yīng)用程序?qū)嵗膔un方法啟動(dòng)WEB服務(wù)器 if __name__ == '__main__':app.run()查看視圖函數(shù)中的路由:
?
給路由傳參示例:
有時(shí)我們需要將同一類URL映射到同一個(gè)視圖函數(shù)處理,比如:使用同一個(gè)視圖函數(shù) 來(lái)顯示不同用戶的個(gè)人信息。
# 路由傳遞的參數(shù)默認(rèn)當(dāng)做string處理,這里指定int,尖括號(hào)中冒號(hào)后面的內(nèi)容是動(dòng)態(tài)的 @app.route('/user/<int:id>') def hello_itcast(id):return 'hello itcast %d' %id?
返回狀態(tài)碼示例:
return后面可以自主定義狀態(tài)碼(即使這個(gè)狀態(tài)碼不存在)。當(dāng)客戶端的請(qǐng)求已經(jīng)處理完成,由視圖函數(shù)決定返回給客戶端一個(gè)狀態(tài)碼,告知客戶端這次請(qǐng)求的處理結(jié)果。
@app.route('/') def hello_itcast():return 'hello itcast',999?
abort函數(shù):
如果在視圖函數(shù)執(zhí)行過(guò)程中,出現(xiàn)了異常錯(cuò)誤,我們可以使用abort函數(shù)立即終止視圖函數(shù)的執(zhí)行。通過(guò)abort函數(shù),可以向前端返回一個(gè)http標(biāo)準(zhǔn)中存在的錯(cuò)誤狀態(tài)碼,表示出現(xiàn)的錯(cuò)誤信息。
使用abort拋出一個(gè)http標(biāo)準(zhǔn)中不存在的自定義的狀態(tài)碼,沒(méi)有實(shí)際意義。如果abort函數(shù)被觸發(fā),其后面的語(yǔ)句將不會(huì)執(zhí)行。其類似于python中raise。
from flask import Flask,abort @app.route('/') def hello_itcast():abort(404)return 'hello itcast',999捕獲異常:
在Flask中通過(guò)裝飾器來(lái)實(shí)現(xiàn)捕獲異常,errorhandler()接收的參數(shù)為異常狀態(tài)碼。視圖函數(shù)的參數(shù),返回的是錯(cuò)誤信息。
@app.errorhandler(404) def error(e):return '您請(qǐng)求的頁(yè)面不存在了,請(qǐng)確認(rèn)后再次訪問(wèn)!%s'%e?
重定向redirect示例
from flask import redirect @app.route('/') def hello_itcast():return redirect('http://www.itcast.cn')?
正則URL示例:
正則URL是為了匹配指定的URL,而匹配指定的URL則可以達(dá)到限制訪問(wèn),以及優(yōu)化訪問(wèn)路徑的目的。
from flask import Flask from werkzeug.routing import BaseConverterclass Regex_url(BaseConverter):def __init__(self,url_map,*args):super(Regex_url,self).__init__(url_map)self.regex = args[0]app = Flask(__name__) app.url_map.converters['re'] = Regex_url@app.route('/user/<re("[a-z]{3}"):id>') def hello_itcast(id):return 'hello %s' %id設(shè)置cookie和獲取cookie
from flask import Flask,make_response @app.route('/cookie') def set_cookie():resp = make_response('this is to set cookie')resp.set_cookie('username', 'itcast')return resp from flask import Flask,request #獲取cookie @app.route('/request') def resp_cookie():resp = request.cookies.get('username')return resp2.2 擴(kuò)展
上下文:相當(dāng)于一個(gè)容器,保存了Flask程序運(yùn)行過(guò)程中的一些信息。
Flask中有兩種上下文,請(qǐng)求上下文和應(yīng)用上下文。
請(qǐng)求上下文(request context)
request和session都屬于請(qǐng)求上下文對(duì)象。
request:封裝了HTTP請(qǐng)求的內(nèi)容,針對(duì)的是http請(qǐng)求。舉例:user = request.args.get('user'),獲取的是get請(qǐng)求的參數(shù)。
session:用來(lái)記錄請(qǐng)求會(huì)話中的信息,針對(duì)的是用戶信息。舉例:session['name'] = user.id,可以記錄用戶信息。還可以通過(guò)session.get('name')獲取用戶信息。
應(yīng)用上下文(application context)
current_app和g都屬于應(yīng)用上下文對(duì)象。
current_app:表示當(dāng)前運(yùn)行程序文件的程序?qū)嵗N覀兛梢酝ㄟ^(guò)current_app.name打印出當(dāng)前應(yīng)用程序?qū)嵗拿帧?/p>
?
g:處理請(qǐng)求時(shí),用于臨時(shí)存儲(chǔ)的對(duì)象,每次請(qǐng)求都會(huì)重設(shè)這個(gè)變量。比如:我們可以獲取一些臨時(shí)請(qǐng)求的用戶信息。
- 當(dāng)調(diào)用app = Flask(_name_)的時(shí)候,創(chuàng)建了程序應(yīng)用對(duì)象app;
- request 在每次http請(qǐng)求發(fā)生時(shí),WSGI server調(diào)用Flask.call();然后在Flask內(nèi)部創(chuàng)建的request對(duì)象;
- app的生命周期大于request和g,一個(gè)app存活期間,可能發(fā)生多次http請(qǐng)求,所以就會(huì)有多個(gè)request和g。
- 最終傳入視圖函數(shù),通過(guò)return、redirect或render_template生成response對(duì)象,返回給客戶端。
區(qū)別:?請(qǐng)求上下文:保存了客戶端和服務(wù)器交互的數(shù)據(jù)。 應(yīng)用上下文:在flask程序運(yùn)行過(guò)程中,保存的一些配置信息,比如程序文件名、數(shù)據(jù)庫(kù)的連接、用戶信息等。
請(qǐng)求鉤子
在客戶端和服務(wù)器交互的過(guò)程中,有些準(zhǔn)備工作或掃尾工作需要處理,比如:在請(qǐng)求開(kāi)始時(shí),建立數(shù)據(jù)庫(kù)連接;在請(qǐng)求結(jié)束時(shí),指定數(shù)據(jù)的交互格式。為了讓每個(gè)視圖函數(shù)避免編寫(xiě)重復(fù)功能的代碼,Flask提供了通用設(shè)施的功能,即請(qǐng)求鉤子。
請(qǐng)求鉤子是通過(guò)裝飾器的形式實(shí)現(xiàn),Flask支持如下四種請(qǐng)求鉤子:
before_first_request:在處理第一個(gè)請(qǐng)求前運(yùn)行。
before_request:在每次請(qǐng)求前運(yùn)行。
after_request:如果沒(méi)有未處理的異常拋出,在每次請(qǐng)求后運(yùn)行。
teardown_request:在每次請(qǐng)求后運(yùn)行,即使有未處理的異常拋出。
Flask裝飾器路由的實(shí)現(xiàn):
Flask有兩大核心:Werkzeug和Jinja2。Werkzeug實(shí)現(xiàn)路由、調(diào)試和Web服務(wù)器網(wǎng)關(guān)接口。Jinja2實(shí)現(xiàn)了模板。
Werkzeug是一個(gè)遵循WSGI協(xié)議的python函數(shù)庫(kù)。其內(nèi)部實(shí)現(xiàn)了很多Web框架底層的東西,比如request和response對(duì)象;與WSGI規(guī)范的兼容;支持Unicode;支持基本的會(huì)話管理和簽名Cookie;集成URL請(qǐng)求路由等。
Werkzeug庫(kù)的routing模塊負(fù)責(zé)實(shí)現(xiàn)URL解析。不同的URL對(duì)應(yīng)不同的視圖函數(shù),routing模塊會(huì)對(duì)請(qǐng)求信息的URL進(jìn)行解析,匹配到URL對(duì)應(yīng)的視圖函數(shù),以此生成一個(gè)響應(yīng)信息。
routing模塊內(nèi)部有Rule類(用來(lái)構(gòu)造不同的URL模式的對(duì)象)、Map類(存儲(chǔ)所有的URL規(guī)則)、MapAdapter類(負(fù)責(zé)具體URL匹配的工作);
Flask-Script擴(kuò)展命令行
通過(guò)使用Flask-Script擴(kuò)展,我們可以在Flask服務(wù)器啟動(dòng)的時(shí)候,通過(guò)命令行的方式傳入?yún)?shù)。而不僅僅通過(guò)app.run()方法中傳參,比如我們可以通過(guò)python hello.py runserver --host ip地址,告訴服務(wù)器在哪個(gè)網(wǎng)絡(luò)接口監(jiān)聽(tīng)來(lái)自客戶端的連接。默認(rèn)情況下,服務(wù)器只監(jiān)聽(tīng)來(lái)自服務(wù)器所在計(jì)算機(jī)發(fā)起的連接,即localhost連接。
我們可以通過(guò)python hello.py runserver --help來(lái)查看參數(shù)。
from flask import Flask from flask_script import Managerapp = Flask(__name__)manager = Manager(app)@app.route('/') def index():return '床前明月光'if __name__ == "__main__":manager.run()?
?
?
總結(jié)
以上是生活随笔為你收集整理的【python】Flask视图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: beeline连接hiveserver2
- 下一篇: [Openstack] 使用heat模板
