flask(2.0)

一. Flask基礎(一)

1.Flask啓動

from flask import Flask
app = Flask(__name__)
@app.route("/index"):
def index():
    return "Hello"
app.run(host="0.0.0.0", port=9527, debug=True)

2.路由

methods = ["GET", "POST", "PUT", "DELETE"]

# 示例:
@app.route("/index", methods=["POAT", "GET"])

3.Response

# 5個返回類型:

# 三劍客
1. 直接返回字符串 HttpResponse
2. 返回模板字符串 render_template
3. 重定向 redirect

# 兩個特殊值
4. 打開並返回文件內容 send_file("文件的路徑")
5. 標準JSON格式的Response jsonify({"name":"Tom"})
    Content-type:application/json

4.Request

from flask import request
1. method   # 獲取當前請求的 請求方式
2. url      # 獲取完整訪問路徑,包含url參數
3. path     # 獲取路由地址
4. form     # 獲取FormData中的數據
    - to_dict()
    - get()
5. args     # 獲取url中的參數數據
    - to_dict()
    - get()
6. values   # 深坑,一般用於查看args和FormData中的數據
7. json     # 請求頭中Content-type:application/json數據會存放在request.json中
8. data     # 請求頭中Content-type不被承認時,會將原始的請求體中的數據存放成Bytes類型的數據,Content-type:application/json也會保存原始請求體信息

5.Jinja2

{{}}    # 變量,函數
{%%}    # 邏輯代碼

6.session

from flask import session   # 導入session
app.secret_key = "~!@#$%^"  # 設置反序列化祕鑰
session["user"] = "value"   # 添加一個session值

Flask會將序列化後的session字符串存放在客戶端的cookies中.python

二.Flask基礎(二)

1.路由配置

@app.route()裝飾器中的參數:
    methods
    endpoint
    defaults
    strict_slashes
    redirect_to
    subdomain

(1)methods

描述: 容許進入當前視圖函數的請求方式.json

@app.route("/index", methods=["GET", "POST"])
def index():
    return "index"

注意: 不寫methods參數時默認是隻容許GET請求, 寫methods參數時要指定全部容許的請求方式, 默認方式會被methods覆蓋.flask

(2)endpoint

描述: 反向url地址,默認爲視圖函數名, url_for利用它進行反向解析.瀏覽器

from flask import Flask, url_for

@app.route("/info", methods=["GET", "POST"], endpoint='s_info')
def stu_info():
    print(url_for('s_info')) # 利用s_info反向解析本視圖函數的路由地址 /info
    return "student info"

注意: endpoint默認與視圖函數名一致, 不寫endpoint參數則使用視圖函數名反向解析, 即url_for('stu_info'), 有endpoint參數則使用該參數進行反向解析.緩存

(3)defaults

描述: 視圖函數的參數默認值.安全

@app.route("/info", methods=["GET", "POST"], defaults={"nid": 100})
def stu_info(nid):
    print(nid)   # 100
    return "student info"

注意: 視圖函數必定要接收這個參數, 且形參名稱必定要與defaults參數中的key保持一致.服務器

(4)strict_slashes

描述: 是否嚴格遵照URL地址規則, 若strict_slashes=True, 那麼在url地址末尾不能夠出現斜杆/, 反之則能夠.cookie

(5)redirect_to

描述: 永久重定向session

# 訪問地址: /info 瀏覽器跳轉至 /infos

@app.route("/info", redirect_to="/infos")
def student_info():
    return "Hello info"

@app.route("/infos")
def student_infos():
    return "Hello infos"

注意: 在跳轉以前進行重定向, 原url對應的視圖函數沒有執行, 當即跳轉到新的url, 且使用一次後瀏覽器會有緩存.

(6)subdomain

描述: 子域名前綴 subdomian="car" 這樣寫能夠獲得 car.oldboy.com 前提是app.config["SERVER_NAME"] = "oldboy.com"

app.config["SERVER_NAME"] = "oldboy.com"

@app.route("/info",subdomain="car")
def student_info():
    return "Hello info"

# 訪問地址爲:  car.oldboy.com/inf

2.動態路由參數

實例1

from flask import Flask, url_for

app = Flask(__name__)

@app.route("/info/<int:nid>", methods=["GET", "POST"], endpoint="s_info")
def student_info(nid):
    print(nid, type(nid))   # 1 <class 'int'>
    print(url_for("s_info", nid=nid))  # /info/1
    print(url_for("s_info", nid=2))    # /info/2
    return "Hello info"

app.run()

# 訪問地址: http://127.0.0.1:5000/info/1  能夠
# 訪問地址: http://127.0.0.1:5000/info/e  報錯

實例2

from flask import Flask, url_for

app = Flask(__name__)

@app.route("/info/<string:nid>", methods=["GET", "POST"], endpoint="s_info")
def student_info(nid):
    print(nid, type(nid))   # 1 <class 'str'>
    return "Hello info"

app.run()

# 訪問地址:  http://127.0.0.1:5000/info/1   能夠   
# 訪問地址:  http://127.0.0.1:5000/info/e   能夠

實例3

from flask import Flask, url_for

app = Flask(__name__)

@app.route("/info/<nid>", methods=["GET", "POST"], endpoint="s_info")
def student_info(nid):
    print(nid, type(nid))   # 1 <class 'str'>
    return "Hello info"

app.run()

# 訪問地址:  http://127.0.0.1:5000/info/1    能夠
# 訪問地址:  http://127.0.0.1:5000/info/e    能夠

總結

經過以上示例發現, <int:nid>就是在url後定義一個參數接收url中的參數, 當定義int類型時只能傳數字, 當定義string類型時能夠接收數字和字符串, 當不定義類型時, 默認是string類型.

注意: 這種動態參數路由, 在url_for的時候, 必定要將動態參數名+參數值添加進去, 不然會拋出參數錯誤的異常.

3.Flask實例化配置

app = Flask(__name__, )

實例化對象時的參數以下:

# 經常使用:
template_folder="templates"     # 默認模板存放目錄 templates
static_folder="static"          # 默認靜態文件存放目錄 static
static_url_path="/static"       # 訪問靜態文件路由地址,默認是"/"+static_folder

# 不經常使用:
static_host=None        # 指定靜態文件服務器地址
host_matching=False     # 若不是特別須要時,慎用,不然全部的route 都須要host=""的參數
instance_path=None      # 指向另外一個Flask實例的路徑
root_path=None          # 主模塊所在的目錄的絕對路徑,默認項目目錄

4.Flask對象配置

Flask對象即Flask的實例化對象app, Flask的對象配置就是在 app.config 中添加鍵值對, 例如, app.config["SECRET_KEY"]="/wrwfgs", 可是你存進去的鍵必須是config中應該存在的, 若是不存在的話, 它沒有任何用處, 因此咱們來看一下config中有哪些key以及對應的做用.

  'DEBUG': False,  # 是否開啓Debug模式
  'TESTING': False,  # 是否開啓測試模式
  'SECRET_KEY': None # 在啓用Flask內置Session的時候/開啓flash,必定要有它
  'PERMANENT_SESSION_LIFETIME': 31,  # days , Session的生命週期(天)默認31天
  'SESSION_COOKIE_NAME': 'session',  # 在cookies中存放session加密字符串的名字

  'PROPAGATE_EXCEPTIONS': None,  # 異常傳播(是否在控制檯打印LOG) 當Debug或者testing開啓後,自動爲True
  'PRESERVE_CONTEXT_ON_EXCEPTION': None,  # 一兩句話說不清楚,通常不用它
  'SECRET_KEY': None,  # 以前遇到過,在啓用Session的時候,必定要有它
  'PERMANENT_SESSION_LIFETIME': 31,  # days , Session的生命週期(天)默認31天
  'USE_X_SENDFILE': False,  # 是否棄用 x_sendfile
  'LOGGER_NAME': None,  # 日誌記錄器的名稱
  'LOGGER_HANDLER_POLICY': 'always',
  'SERVER_NAME': None,  # 服務訪問域名
  'APPLICATION_ROOT': None,  # 項目的完整路徑
  'SESSION_COOKIE_NAME': 'session',  # 在cookies中存放session加密字符串的名字
  'SESSION_COOKIE_DOMAIN': None,  # 在哪一個域名下會產生session記錄在cookies中
  'SESSION_COOKIE_PATH': None,  # cookies的路徑
  'SESSION_COOKIE_HTTPONLY': True,  # 控制 cookie 是否應被設置 httponly 的標誌,
  'SESSION_COOKIE_SECURE': False,  # 控制 cookie 是否應被設置安全標誌
  'SESSION_REFRESH_EACH_REQUEST': True,  # 這個標誌控制永久會話如何刷新
  'MAX_CONTENT_LENGTH': None,  # 若是設置爲字節數, Flask 會拒絕內容長度大於此值的請求進入,並返回一個 413 狀態碼
  'SEND_FILE_MAX_AGE_DEFAULT': 12,  # hours 默認緩存控制的最大期限
  'TRAP_BAD_REQUEST_ERRORS': False,
  # 若是這個值被設置爲 True ,Flask不會執行 HTTP 異常的錯誤處理,而是像對待其它異常同樣,
  # 經過異常棧讓它冒泡地拋出。這對於須要找出 HTTP 異常源頭的可怕調試情形是有用的。
  'TRAP_HTTP_EXCEPTIONS': False,
  # Werkzeug 處理請求中的特定數據的內部數據結構會拋出一樣也是「錯誤的請求」異常的特殊的 key errors 。
  # 一樣地,爲了保持一致,許多操做能夠顯式地拋出 BadRequest 異常。
  # 由於在調試中,你但願準確地找出異常的緣由,這個設置用於在這些情形下調試。
  'EXPLAIN_TEMPLATE_LOADING': False,  # 若是這個值被設置爲True,你只會獲得常規的回溯。
  'PREFERRED_URL_SCHEME': 'http',  # 生成URL的時候若是沒有可用的 URL 模式話將使用這個值
  'JSON_AS_ASCII': True,
  # 默認狀況下 Flask 使用 ascii 編碼來序列化對象。若是這個值被設置爲 False ,
  # Flask不會將其編碼爲 ASCII,而且按原樣輸出,返回它的 unicode 字符串。
  # 好比 jsonfiy 會自動地採用 utf-8 來編碼它而後才進行傳輸。
  'JSON_SORT_KEYS': True,
  # 默認狀況下 Flask 按照 JSON 對象的鍵的順序來序來序列化它。
  # 這樣作是爲了確保鍵的順序不會受到字典的哈希種子的影響,從而返回的值每次都是一致的,不會形成無用的額外 HTTP 緩存。
  # 你能夠經過修改這個配置的值來覆蓋默認的操做。但這是不被推薦的作法由於這個默認的行爲可能會給你在性能的代價上帶來改善。
  'JSONIFY_PRETTYPRINT_REGULAR': True,
  'JSONIFY_MIMETYPE': 'application/json',
  'TEMPLATES_AUTO_RELOAD': None,
"""
查看全部配置項:
app.default_config
"""

以上這些key均可以被改寫, 固然它們也有默認值, 若是沒有特殊狀況, 不要改寫它的默認值.

除了單獨修改某一項的配置外, 還能夠經過類的方式導入配置:

# 新建settings.py文件

class MyConfig(object):
    DEBUG = True
    SECRET_KEY = "~!@#$%^"
    SESSION_COOKIE_NAME = "flask_session"
# 在flask啓動文件中加載配置項

from flask import Flask
app = Flask(__name__)

from settings import MyConfig       # 導入配置文件
app.config.from_object(MyConfig)    # 加載配置文件

5.特殊裝飾器

描述: 相似於Django的中間件.

from flask import Flask

app = Flask(__name__)

@app.before_request
def be1():
    print('我是be1')

@app.before_request
def be2():
    print('我是be2')

@app.before_request
def be3():
    print('我是be3')

@app.after_request
def af1(response):
    print('我是af1')
    return response

@app.after_request
def af2(response):
    print('我是af2')
    return response

@app.after_request
def af3(response):
    print('我是af3')
    return response

@app.route('/index')
def index():
    print('我是視圖函數')
    return 'ok'

if __name__ == '__main__':
    app.run(debug=True)
# 總結:
before_request  # 在請求進入視圖函數以前做出響應
after_request   # 在視圖函數處理以後,響應返回客戶端以前

# 代碼書寫順序:
    be1 -> be2 -> be3 -> view -> af1 -> af2 -> af3
# 代碼執行順序:
    正常狀況: 返回順序是書寫代碼時的倒序
    be1 -> be2 -> be3 -> view -> af3 -> af2 -> af1
    異常狀況: 異常阻塞請求的狀況,不通過視圖函數
    be1 -> af3 -> af2 -> af1

6.重定義錯誤提示errorhandler

from falsk import Flask, render_template

app = Flask(__name__)

@app.errorhandler(404)  # 參數是錯誤碼
def error404(error_msg):    # 必須接收錯誤信息
    print(error_msg)
    return render_template("error404.html")

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

7.before_first_request

@app.before_first_request   # 當前客戶端第一次訪問此應用(不會被阻塞)
def bfe():
    print("當前客戶端第一次訪問此應用")
    return "ok"

8.Flask藍圖(Blueprint)

實例一

初學flask, 能夠將藍圖理解爲沒有run方法的Flask對象.

# 新建flask_project/app01/views.py

from flask import Blueprint     # 導入藍圖

bp1 = Blueprint("bp1", __name__)    # 實例化藍圖對象

@bp1.route("/stulist")
def stulist():
    return "student list"
# 新建flask_project/manage.py

from flask import Flask
from app01 import views

app = Flask(__name__)

app.register_blueprint(views.bp1)   # 註冊藍圖

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

運行manage.py文件啓動flask項目, 瀏覽器訪問http://127.0.0.1:5000/stulist便可看到返回結果.

藍圖能夠指定url前綴(url_prefix參數), 有以下兩種方法:

  • 方法一: 實例化藍圖對象時指定url前綴

    • bp1 = Blueprint("bp1", __name__, url_prefix="app01")
  • 方法二: 在註冊藍圖時指定url前綴

    • app.register_blueprint(views.bp1, url_prefix="app01")

此時, 瀏覽器訪問http://127.0.0.1:5000/app01/stulist可看到返回結果.

實例二

# app01/views/user.py

from flask import Blueprint

user_bp = Blueprint("user", __name__, url_prefix="/app01")


@user_bp.route("/user")
def user():
    return "I am user Blueprint"
# app01/__init__.py

from flask import Flask
from app01.views.user import user_bp


def create_app01():
    app01 = Flask(__name__)
    app01.register_blueprint(user_bp)
    return app01
# manager.py

from app01 import create_app01

my_app01 = create_app01()

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

三.藍圖實例演練

基於藍圖實現一個內存增刪改查, 數據以下:

STUDENT_DICT = {
    1: {'name': 'Old', 'age': 38, 'gender': '中'},
    2: {'name': 'Boy', 'age': 73, 'gender': '男'},
    3: {'name': 'EDU', 'age': 84, 'gender': '女'},
}

待續...

相關文章
相關標籤/搜索