2.8.6Flask --2 Flask路由,請求與響應提佣,重定向

Flask目錄:http://www.reibang.com/p/9b5e30320849

路由

路由充當了一個指路牌的作用吮蛹,讓用戶訪問想要訪問的頁面得到想要的數(shù)據(jù)。


路由

當然也可以多個頁面指向同一個路由(不過這樣肯定是有關聯(lián)的頁面拌屏,最好使用正則URL)

路由配置

Flask的路由配置是沒有專門的文件存放的潮针,基本是以裝飾器的形式存在視圖函數(shù)頂部。
實例:

from flask import Flask
app = Flask(__name__)

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

#路由裝飾器,語法為 app.route(url_name,methods)  
#url_name:路由名
#methods:請求方式倚喂,默認get請求,可以使用列表指定多種方式每篷。例:['GET','POST']
@app.route('/index')
def hi_flask():
    return 'Hi,Flask'

if __name__ == '__main__':
    app.run()
頁面截圖

同時,路由也有多種寫法:

參數(shù)傳遞:@app.route('/users/<username>')
指定類型:@app.route('/users/<int:pwd>')


參數(shù)類型表

一個簡單的傳參請求

實例:

from flask import Flask,url_for
app = Flask(__name__)

#使用參數(shù)接受url
@app.route('/user/<username>')
#給username設置一個默認值端圈,這樣不輸入username也可以訪問到這個頁面焦读。
def users(username=''):
    return "用戶名:{}".format(username)

if __name__ == '__main__':
    app.run()
頁面截圖

同時還有另外一種方式,就是API方式枫笛。
實例:

from flask import Flask
app = Flask(__name__)

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

def hi_flask2():
    return 'Hi,Flask2'
app.add_url_rule("/index2/", view_func=hi_flask2)
#API函數(shù)吨灭,第一個參數(shù)是路由名,第二個參數(shù)要以關鍵字參數(shù)傳入刑巧,值是一個配套的函數(shù)名喧兄。
if __name__ == '__main__':
    app.run()
頁面截圖

這兩種方式的詳解

首先我們從裝飾器入手:

源碼如下
-------
    def route(self, rule, **options):
        """A decorator that is used to register a view function for a
        given URL rule.  This does the same thing as :meth:`add_url_rule`
        but is intended for decorator usage::

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

        For more information refer to :ref:`url-route-registrations`.

        :param rule: the URL rule as string
        :param endpoint: the endpoint for the registered URL rule.  Flask
                         itself assumes the name of the view function as
                         endpoint
        :param options: the options to be forwarded to the underlying
                        :class:`~werkzeug.routing.Rule` object.  A change
                        to Werkzeug is handling of method options.  methods
                        is a list of methods this rule should be limited
                        to (``GET``, ``POST`` etc.).  By default a rule
                        just listens for ``GET`` (and implicitly ``HEAD``).
                        Starting with Flask 0.6, ``OPTIONS`` is implicitly
                        added and handled by the standard request handling.
        """

        def decorator(f):
            endpoint = options.pop("endpoint", None)
            self.add_url_rule(rule, endpoint, f, **options)  
            #這里調用了add_url_rule
            return f

        return decorator
也就是說,route只不過是封裝了一下的裝飾器啊楚,干活的還是add_url_rule吠冤。
這樣的話,大家直接用裝飾器就好了恭理。

路由反向解析

說到路由拯辙,就不能不能不說路由的反向解析,他可以幫助我們獲得用戶請求的路由與配套的視圖函數(shù)。
實例:

from flask import Flask,url_for
app = Flask(__name__)

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

#路由裝飾器, 語法為 app.route(url_name,method)  前者是路由名涯保, 后者是請求方式诉濒,默認get請求
@app.route('/index')
def hi_flask():
    return 'Hi,Flask'

def hi_flask2():
    return 'Hi,Flask2'

app.add_url_rule("/index2/", view_func=hi_flask2)
#API函數(shù),第一個參數(shù)是路由名夕春,第二個參數(shù)要以關鍵字參數(shù)傳入未荒,值是一個配套的函數(shù)名。

# 查看URL規(guī)則
print(app.url_map)

# 反向解析及志,通過視圖名找到對應的路由
with app.test_request_context():
    print(url_for('hello_world'))
    print(url_for('hi_flask2'))

if __name__ == '__main__':
    app.run()
輸出結果:
--------
Map([<Rule '/index2/' (GET, OPTIONS, HEAD) -> hi_flas2k>,
 <Rule '/index' (GET, OPTIONS, HEAD) -> hi_flask>,
 <Rule '/' (GET, OPTIONS, HEAD) -> hello_world>,
 <Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>])
/
/index2/

當然 url_for()還有很多其他的功能片排,以后會慢慢說。

請求與響應

上下文

上下文分為速侈,請求上下文與應用上下文率寡。用語文中的概念來理解即可。在計算機中倚搬,可以把它理解為環(huán)境冶共。

引用上下文

current_app:當前應用的案例
g:處理請求時的臨時存儲對象,每次請求都會重設這個對象

請求上下文

request:請求對象每界,封裝了客戶端發(fā)給服務端的HTTP請求
session:用戶會話比默,在各個會話中共享數(shù)據(jù)

請求

請求分派

請求分派

我們來了一個請求'/index/',那么這個請求該去找哪個url規(guī)則呢盆犁,這個讓請求找到他目的地的過程就是請求分派。

請求報文常用參數(shù)

method:請求的方式(get篡九,post等等)
args:get請求提交的數(shù)據(jù)
form:form表單提交的數(shù)據(jù)
files:文件上傳
cookies:cookie的傳輸
headers:HTTP請求頭

GET請求

from flask import Flask,request
app = Flask(__name__)

@app.route('/user')
def users():
    #request是獲取用戶請求對象谐岁,args是獲取用戶get請求數(shù)據(jù) 數(shù)據(jù)是dict類型。
    get_dict = request.args
    print(get_dict)
    #從數(shù)據(jù)集中獲取某一個值榛臼。
    username = request.args.get('username')
    print(username)
    #既然是dict類型伊佃,還是get方法,肯定能設置默認值啦沛善。
    page = request.args.get('page',1)
    print(page)
    return "用戶名:{}".format(username)

if __name__ == '__main__':
    app.run()
----------
輸出結果:
ImmutableMultiDict([('username', 'lisi')])
lisi
1
image.png

POST請求

在將模板操作時一起說鲁纠。

請求頭

headers是一個字典類型的數(shù)據(jù)竞膳,獲取后還可以通過get函數(shù)得到我們想要的數(shù)據(jù),例如請求的ip,系統(tǒng)平臺等等专酗。

from flask import Flask,request
app = Flask(__name__)

@app.route('/user')
def users():
    headers = request.headers
    return "請求頭:{}".format(headers)

if __name__ == '__main__':
    app.run()
請求頭

請求鉤子

請求鉤子就是用來校驗用戶請求舒服是否合法。有四個常用函數(shù)

  • before_first_request
    服務器初始化后第一個請求到達前執(zhí)行
  • before_request
    每一個請求到達前執(zhí)行
  • after_request
    每次請求處理完成后執(zhí)行呐馆,如果請求過程中產生了日常风科,則不執(zhí)行。
  • teardown_request
    每次請求處理完成后執(zhí)行产捞,如果請求過程中發(fā)生了異常也執(zhí)行醇锚。
    實例1:
from flask import Flask,request
app = Flask(__name__)

@app.before_first_request
def first_req():
    print('first_request')
    print('------')

@app.before_request
def before_req():
    print('brfore_request')
    print('------')


@app.route('/user')
def users():
    get_dict = request.args
    print(get_dict)
    print('------')
    return "請求參數(shù):{}".format(get_dict)

if __name__ == '__main__':
    app.run()
請求前

before_first_request函數(shù)確實只在確認連接的時候認證一次,而before_request會對每一次連接進行認證坯临。

實例2:

from flask import Flask,request
app = Flask(__name__)

@app.before_first_request
def first_req():
    print('first_request')
    print('------')

@app.before_request
def before_req():
    print('brfore_request')
    print('------')

@app.after_request
def after_req(resp):
    print('after_request')
    print('------')
    return resp

@app.route('/user')
def users():
    get_dict = request.args
    print(get_dict)
    print('------')
    return "請求參數(shù):{}".format(get_dict)

if __name__ == '__main__':
    app.run()
輸出結果

只要請求內部不報錯焊唬, after_request就會完美執(zhí)行恋昼。

teardown_request可以作為一個異常處理的方法,我們這里不探究他的使用赶促。

響應

我們處理完用戶的請求液肌,反饋給用戶的數(shù)據(jù)就是響應。響應可以是各種數(shù)據(jù)芳杏。其中特殊的包括我們反饋的數(shù)據(jù)矩屁,頁面,狀態(tài)碼和響應頭爵赵。


404

我們請求一個不存在的頁面吝秕,肯定會得到404的狀態(tài)碼。但是我們不想返回這個樸素的頁面空幻,這就需要我們的響應定制了烁峭。

from flask import Flask,request
app = Flask(__name__)

@app.errorhandler(404)
def not_fount(err):
    print(err)
    return '你要找的頁面找不到了'

if __name__ == '__main__':
    app.run()
自定義404

同時我們也可以修改一下返回的數(shù)據(jù),例如狀態(tài)碼或者headers秕铛。

@app.errorhandler(404)
def not_fount(err):
    print(err)
    return '你要找的頁面找不到了',404,{
        'is_login':False
    }
自定義404

接著來看響應經常用到的方法:

make_response():相當于Django中的HttpResponse约郁。
from flask import Flask,make_response
app = Flask(__name__)

@app.route('/test')
def test():
    make = make_response("<h1>這是一個測試頁面</h1>",200)
    return make

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

但是一般我們都是返回一個頁面的:

from flask import Flask,make_response,render_template
app = Flask(__name__)

@app.route('/test')
def test():
    tmp = render_template('index.html')
    make = make_response(tmp,200)
    return make

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

make_response 想要返回頁面,不能直接寫做:make_response('hello.html')但两,必須用render_template('hello.html')形式鬓梅。

重定向

redirect():相當于 Django中的HttpResponseRedirect。
from flask import Flask,make_response
app = Flask(__name__)

@app.route('/test')
def test():
    make = make_response("<h1>這是一個測試頁面</h1>",200)
    return make

@app.route('/test1')
def test1():
    return redirect('/test')

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

同時還有一個中止重定向的函數(shù):
abort()函數(shù)用于提前退出一個請求谨湘,并用指定的錯誤碼返回绽快。

from flask import Flask,make_response
app = Flask(__name__)

@app.route('/test')
def test():
    make = make_response("<h1>這是一個測試頁面</h1>",200)
    return make

@app.route('/test1')
def test1():
    headers = request.headers
    ip = headers.get('host')
    print(ip)
    ip_list = ['127.0.0.1:5000']
    if ip in ip_list:
        abort(403)
    return redirect('/test')

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

我們這里模仿了一個ip請求黑白名單的訪問。如果請求ip是我們的黑名單ip紧阔,就拋出一個403請求中斷當前請求坊罢。


abort
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市擅耽,隨后出現(xiàn)的幾起案子活孩,更是在濱河造成了極大的恐慌,老刑警劉巖乖仇,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件憾儒,死亡現(xiàn)場離奇詭異,居然都是意外死亡乃沙,警方通過查閱死者的電腦和手機航夺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崔涂,“玉大人阳掐,你說我怎么就攤上這事。” “怎么了缭保?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵汛闸,是天一觀的道長。 經常有香客問我艺骂,道長诸老,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任钳恕,我火速辦了婚禮别伏,結果婚禮上,老公的妹妹穿的比我還像新娘忧额。我一直安慰自己厘肮,他們只是感情好,可當我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布睦番。 她就那樣靜靜地躺著类茂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪托嚣。 梳的紋絲不亂的頭發(fā)上巩检,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天,我揣著相機與錄音示启,去河邊找鬼兢哭。 笑死,一個胖子當著我的面吹牛夫嗓,可吹牛的內容都是我干的厦瓢。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼啤月,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了劳跃?” 一聲冷哼從身側響起谎仲,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刨仑,沒想到半個月后郑诺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡杉武,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年辙诞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轻抱。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡飞涂,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情较店,我是刑警寧澤士八,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站梁呈,受9級特大地震影響婚度,放射性物質發(fā)生泄漏。R本人自食惡果不足惜官卡,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一蝗茁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寻咒,春花似錦哮翘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至熔脂,卻和暖如春佩研,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背霞揉。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工旬薯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人适秩。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓绊序,卻偏偏與公主長得像,于是被迫代替她去往敵國和親秽荞。 傳聞我的和親對象是個殘疾皇子骤公,可洞房花燭夜當晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內容