三十、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('/<int:agrs>')
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 使用配置模組:
配置模組程式碼例項:
# 基礎配置
class Config:
DEBUG = None
SECRET_KEY = “20181015” # 設定祕鑰
# 開發模式
class DevelopmentConfig(Config):
DEBUG = True
# 生產模式
class ProductionConfig(Config):
DEBUG = False
# 定義字典對映
config_dict = {
'development': DevelopmentConfig,
'production': ProductionConfig
}
實現程式碼例項:
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) // 在每次請求後執行,接受一個引數:錯誤資訊,如果有相關錯誤丟擲