1. 程式人生 > >三十、python之Flask框架(二)檢視:返回狀態碼、重定向、狀態保持、請求鉤子

三十、python之Flask框架(二)檢視:返回狀態碼、重定向、狀態保持、請求鉤子

一、返回狀態碼和abort函式

1.return直接返回狀態碼:

return可以返回自定義的不符合http協議的狀態碼。
作用:實現前後端的資料互動。
程式碼:

from flask import Flask
app = Flask(__name__)


@app.route("/")
def index():
    return "hello world!!", 600	# 返回自定的600狀態碼

if __name__ == '__main__':
    app.run(host="0.0.0.", debug=True)

2.abort函式:

2.1 abort函式:

abort函式:flask中的異常處理語句,功能類似於python中raise語句,只要觸發abort後面的程式碼不會執行。
結論:abort只能丟擲符合http協議的異常狀態碼。
作用:abort函式一般用來實現自定義的錯誤資訊,讓程式碼的擴充套件性更好,提高使用者體驗。

2.2 errorhandler函式:

errorhandler函式接受的引數是abort函式丟擲的錯誤狀態,用來自定義錯誤頁面或者資訊

#!/usr/bin/env python3
# coding=utf-8
from flask import Flask,abort

app = Flask(__name__)

@app.route("/")
def index():
    abort(404)	# 丟擲404狀態碼,但是不會終止程式的繼續執行
    return "Hello World!!"

@app.errorhandler(404)
def error_handler(e):
    print(type(e)) # <class 'werkzeug.exceptions.NotFound'>
    # e的底層是werkzeug.exceptions的例項物件,用來處理相應的狀態碼
    print(e)
    # 404 Not Found: The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.
    
    return "頁面錯誤..."

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

二、重定向(302):

1.重定向:

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

@app.route("/")
def index():
    url = "https://www.baidu.com"
    return redirect(url)

2.什麼是重定向:

訪問當前url,重新請求一個新的url
作用:當網站頁面頁面或者文章發生變化的時候,可以使用重定向,提高使用者體驗。

3.反向解析:url_for

3.1 url_for:

from flask import url_for

@app.route("/demo")
def demo_url_for():
    # url_for接收的引數名為檢視函式名
    return redirect(url_for("index"))

3.2 作用:

建議使用url_for實現頁面的重定向,可以rag重定向定位到具體的檢視函式,讓程式碼不冗餘.

3.3 什麼是反向解析:

正向解析:從url找到檢視函式;
反向解析:從檢視函式找到物件的url;

三、JSON:

1.概念:

基於鍵值對的字串,本質是字串。

2.作用:

輕量級的資料互動方式,用於資料傳輸。

3. 如何實現資料互動:

  • 在json之前的前後端資料傳輸是使用xml格式進行傳輸,
  • xml是一種偏重的資料互動格式,是因為需要打包;
  • json是一種資料格式,不是一種資料型別;

4. python中如何傳輸json:

python中有json模組,dumps和loads

import json
json.dumps(): 把字典(變數)轉換成json字串;
json.loads(): 把json字串轉換成字典(變數);
json.dump():把字典(檔案物件)轉換成json字串
json.load(): 把json字串轉換成字典(檔案物件);

5.flask中如何返回json:

5.1 例項

from flask import Falsk, jsonfiy

@app.route("/")
def index():
    data = {
        'name':'python32',
        'age':18
    }
    # return json.dumps(data)   # Content-Type:text/html
    return jsonfiy(data)    # Content-Type:application/json

5.2 作用:

jsonify的作用:就是把字典轉成json字串,底層封裝了python的json模組

四、給URL傳遞引數<>

1.語法:

<args> // 一般用法.預設是字串
<資料型別:agrs> // 限制資料型別:預設6種, string、int、float、any、path、uuid(全域性唯一的識別符號),使用了flask內建的轉換器,對應6種

寫在route修飾器的地址中

@app.route('/&lt;int:agrs&gt;')
def index(args):
	return "hello World %s" % args

2.實現:

werkzeug.routing Baseconvert
通過werkzeug內建的轉換器內實現(Converter)

3.程式碼:

# !/usr/bin python3
# coding: utf-8
from flask import Flask
from werkzeug.routing import BaseConverter

app = Flask(__name__)

@app.route("/<int:args>")
def index_int(args):
    return "你好世界,%s" %args

@app.route("/<float:args>")
def index_float(args):
    return "你好世界,%s" %args


if __name__ == '__main__':
    app.run(host="0.0.0.0", debug=True)

五、正則URL:

1.需求分析:

內建的轉換器只能限制資料型別,現在我們需要限制引數的引數

2.自定義轉換器:

需要繼承werkzeug.routing包的BaseConverter模組

2.1 自定義轉換器一(固定正則):

先來參考一下werkzeug.routing中,官方的轉化器的寫法:

class FloatConverter(NumberConverter):
    regex = r'\d+\.\d+'
    num_convert = float

    def __init__(self, map, min=None, max=None):
        NumberConverter.__init__(self, map, 0, min, max)

參照原始碼可知,轉換器是繼承於BaseConverter類的

# 自定義轉化器一:正則表示式固定寫死
class RegexConverter1(BaseConverter):
    regex = "[a-z]{6,20}"   # 正則小寫字母6-20個

# 將自定義的轉換器新增到werkzeug.routing的DEFAULT_CONVERTERS關係中
app.url_map.converters['re1'] = RegexConverter1

@app.route("/<re1:args>")
def index(args):
    return "傳入的引數是:%s" %args

缺點:

  • 每一個規則都需要對應一個自定義轉換器,且每一個自定義轉換器都需要新增到werkzeug.routing的DEFAULT_CONVERTERS關係中,不方便。

2.2 自定義轉換器二(通過傳參動態正則)

# 自定義轉換器二:動態的傳入好.正則規則
class RegexConverter2(BaseConverter):
    def __init__(self, map, *args):
        super(RegexConverter2, self).__init__(map)
        print(map)
        self.regex = args[0]
        print("接受到的正則規則是:" + args[0])

app.url_map.converters['re2'] = RegexConverter2

@app.route("/<re2('[\d]{4,6}'):args>")  # 動態的規定正則:0-9接受4-6個
def demo(args):
    return "傳入的引數是:%s" %args

六、狀態保持:

1.狀態保持:

客戶端和伺服器互動,伺服器需要記錄客戶端是誰。

2.cookie和session:

2.1概念:

cookie和session:都是基於鍵值對的字串,用來記錄使用者資訊。

2.2 cookie:

是存出來客戶端瀏覽器;不安全;(同源策略:誰寫的cookie誰能拿到)

2.3 session:

  • 是基於cookie實現的,儲存在伺服器中;和框架和語言無關
  • key儲存在瀏覽器中, 且是經過加密的字串;
  • value儲存到伺服器中

3.設定/獲取cookie

# !/usr/bin python3
# coding:utf-8
from flask import Flask, make_response, request

app = Flask(__name__)

# 設定cookie
@app.route("/set_cookie")
def set_cokkie():
    # 使用flask內建的相應物件
    response = make_response('set cookie')
    # 使用響應來設定cookie, 在客戶端瀏覽器中設定cookie, max_age表示cookie的保持時間,單位是秒
    response.set_cookie('itcast', 'python32', max_age = 3600)
    # 返回響應物件
    return response

# 獲取cookie
@app.route("/get_cookie")
def get_cookie():
    # request是flask內建的請求上寫文物件,cookie是物件的屬性,get表示獲取方法
    itcast = request.cookies.get('itcast')
    return itcast


if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

4.設定/獲取session:

# !/usr/bin python
# coding:utf-8

from flask import Flask, session

app = Flask(__name__)

# session需要設定金鑰用來進行雜湊編碼
app.config['SECRET_KEY'] = "abcdefgh"

# 設定session
@app.route('/set_session')
def set_session():
    # session是flask內建的上下文物件,用來實現狀態保持中的sesion
    # session會對鍵值對進行編碼,讓狀態保持的session資訊更安全
    session['itcast'] = "python32"
    return 'set session success ...'

# 獲取session
@app.route("/get_session")
def get_session():
    itcast = session.get('itcast')
    return itcast
    

if __name__ == '__main__':
    app.run(host="0.0.0.0", debug=True)

七、載入配置檔案:

1.實現形式有三種:

1.使用配置物件(from_object);建議使用此方法,擴充套件性更強
2.使用初始化檔案from_pyfile;
3.使用環境變數from_envvar

2.程式碼實現:

2.1 使用配置模組:

配置模組程式碼例項:

config.py

# 基礎配置
class Config:
    DEBUG = None
    SECRET_KEY = “20181015”  # 設定祕鑰

# 開發模式
class DevelopmentConfig(Config):
    DEBUG = True

# 生產模式
class ProductionConfig(Config):
    DEBUG = False

# 定義字典對映
config_dict = {
    'development': DevelopmentConfig,
    'production': ProductionConfig
}
實現程式碼例項:

hello.py

from flask import Flask
from config import config_dict
# 將配置模組載入進來
...
# 使用配置物件
app.config.from_object(config_dict['development'])
...

2.2 使用使用初始化檔案:

使用初始化檔案程式碼例項:

config.ini

SECRET_KEY = '2018'
DEBUG = True
實現程式碼例項:
from flask import Flask
...
# 使用配置物件
app.config.from_pyfile("config.ini")
...

2.3 使用環境變數:

實現程式碼例項:
from flask import Flask
...
# 使用環境變數
app.config.from_envvar("SETTINGS")
# 引數是設定好的環境變數名
...

八、請求鉤子:

1.什麼是請求鉤子:

相當於python中的初始化函式__init__和解構函式__del__

2.flask中的四種請求鉤子:

# !/usr/bin python
# coding:utf-8
from flask import Flask,abort

app = Flask(__name__)

@app.route("/")
def index():
    return "hello  world"

# 在請求前執行, 只執行一次
@app.before_first_request
def before_first_request():
    print("before_first_request")

# 在請求之前執行,可重複執行
@app.before_request
def before_request():
    abort(404)
    print("before_request")

# 在請求之後執行
@app.after_request
def after_request(response):
    # 沒有異常的情況下在請求後執行,必須接受響應作物件為引數,並返回響應,如果有web伺服器內部異常不會執行
    print("after_request")
    return response

# 在請求之後,出現異常時執行
@app.teardown_request
def teardown_request(e):
    # 在請求之後,必須接受異常作為引數
    print("teardown_request" + "異常:" + str(e))

if __name__ == '__main__':
    app.run(host="0.0.0.0", debug=True)

3.執行順序:

  • before_first_request // 在請求前執行,只執行一次
  • before_request // 在請求前執行,每次都執行
  • 請求
  • after_request(response) // 在請求後執行, 必須接受響應作為物件,並且有- 返回值;如果伺服器內部錯誤,則不會執行
  • teardown_request(error) // 在每次請求後執行,接受一個引數:錯誤資訊,如果有相關錯誤丟擲