天天看點

Flask基礎知識點1一、.基于裝飾器的session通路控制,endpoint路由參數可以解決視圖函數重名的情況。二、Flask中的路由參數三、Flask配置檔案四、Flask的藍圖五、Flask裡面的擴充,相當于django中的中間件六、閃現:flash七、Flask的send_file使用八、Flask的jsonify的使用

一、.基于裝飾器的session通路控制,endpoint路由參數可以解決視圖函數重名的情況。

下面我有一個簡單的需求,就是一個網站有三個頁面,分别是home、index和login界面,使用者隻有當登陸後才可以正常通路home和index頁面,通過裝飾器的方法來實作。接下來看代碼

from flask import Flask, request, render_template, redirect, Markup, session

app = Flask(__name__)
app.secret_key = "abcdefghijklmn"


def wrapper(f):
    def inner(*args, **kwargs):
        if session.get("user"):
            ret = f(*args, **kwargs)
            return ret
        else:
            return redirect("/login")

    return inner


@app.route("/login", methods=("GET","POST"))
def login():
    if request.method == "GET":
        return render_template("login.html")
    if request.method == "POST":
        username = request.form.get("username")
        session["user"] = username
        return "登陸成功"

@app.route("/home", methods=("GET", "POST"))
@wrapper
def home():
    return "這是home界面的内容"

@app.route("/index")
def index():
    return "我是index界面的内容"

app.run()
           

當我們隻對home視圖函數加上認證裝飾器時實作了我們的需求,但是如果你給index也加上認證裝飾器時你就會發現Flask項目啟動不起來了,會報一個這樣的錯誤:

Flask基礎知識點1一、.基于裝飾器的session通路控制,endpoint路由參數可以解決視圖函數重名的情況。二、Flask中的路由參數三、Flask配置檔案四、Flask的藍圖五、Flask裡面的擴充,相當于django中的中間件六、閃現:flash七、Flask的send_file使用八、Flask的jsonify的使用

image.png

這是因為,當我們對一個以上的視圖函數添加了認證裝飾器後 ,認證裝飾器會将視圖函數名替換成裝飾器的内層函數名inner,在記憶體中就會出現視圖函數名重複的情況,這樣Flask的路由裝飾器裝飾視圖函數時就會報錯,解決這個錯誤的方法就是給路由的endpoint參數指定視圖函數名,即:

from flask import Flask, request, render_template, redirect, Markup, session

app = Flask(__name__)
app.secret_key = "abcdefghijklmn"


def wrapper(f):
    def inner(*args, **kwargs):
        if session.get("user"):
            ret = f(*args, **kwargs)
            return ret
        else:
            return redirect("/login")

    return inner


@app.route("/login", methods=("GET","POST"))
def login():
    if request.method == "GET":
        return render_template("login.html")
    if request.method == "POST":
        username = request.form.get("username")
        session["user"] = username
        return "登陸成功"

@app.route("/home",endpoint="home", methods=("GET", "POST"))
@wrapper
def home():
    return "這是home界面的内容"

@app.route("/index",endpoint="index")
@wrapper
def index():
    return "我是index界面的内容"

app.run()
           

二、Flask中的路由參數

  • @app.route()
@app.route(
    "/<age>"                  // 動态路由參數,預設是string,也可以是"/<int:age>"
    redirect_to = "/login"    //不經過視圖函數直接重定向指定url
    defaults = {"age": 999}   //指定預設參數
    endpoint = "home"         //路由别名,用于反向生成URL,即: url_for('名稱')
    methods = ("GET", "POST") //請求方式
    strict_slashes = False    //是否嚴格比對url最後的"/",例:http://127.0.0.1:5000/home 和 
                             //http://127.0.0.1:5000/home/
    )
           

常用動态路由參數有以下五種,所有的路由系統都是基于以下對應關系來處理:

DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}
           

url_for的用法

from flask import Flask,url_for

app = Flask(__name__)

@app.route("/index/<int:age>",endpoint="index")
def index(age):
    url = url_for("index",age = age)
    print(url)      //    "/index/122"
    return "我是index界面的内容"

app.run()
           
  • app.add_url_rule()方法:比@app.route()多了一個 view_func=view_func參數,其他的相同。

三、Flask配置檔案

1. 初始化Flask執行個體時的配置

app = Flask(_name_,template_folder="template",static_folder="static",static_url_path="/static")

  • static_url_path = "/static_folder" 通路靜态目錄檔案時的位址 預設值是等于static_folder的名字,(應用場景描述:當後端static檔案名修改後,加入前端頁面使用了大量的之前的static路徑,可以将static_url_path參數設定為老的,這樣就可以不用修改前端代碼了。)
  • static_folder = "static" 靜态檔案的存放路徑
  • template_folder='templates' 模闆路徑
2. Flask執行個體的配置 app配置
  • 方式一、app.config["DEBUG"] = True

    PS: 由于Config對象本質上是字典,是以還可以使用app.config.update(...)

  • 方式二、app.config.from_object(obj)
class obj():
    DEBUG = True
    SECERT_KEY = "123123"
           
  • 方式三、app.config.from_pyfile("settings.py")

    settings.py

DEBUG = True
SECERT_KEY = "123123"
           
  • 方式四、app.config.from_envvar("環境變量名稱")

    PS:環境變量的值為python檔案名稱名稱,内部調用from_pyfile方法

  • 方式五、app.config.from_json("json檔案名稱")

    PS: JSON檔案名稱,必須是json格式,因為内部會執行json.loads

  • 方式六、app.config.from_mapping({'DEBUG':True})

    PS:字典格式

四、Flask的藍圖

藍圖”和一個Flask應用對象很相似,但是并不是一個Flask應用對象。它是可以注冊到Flask應用上的一系列操作(對于此的了解,後文會詳細講到)。使用“藍圖”,可以實作以下的一些功能:

  • 将Flask應用“分割”為一系列“藍圖”的集合,簡化了大型應用工作的方式;
  • 在Flask應用上,以 URL 字首和或子域名注冊一個藍圖。可以以不同的URL多次注冊一個藍圖;
  • 通過藍圖提供模闆過濾器、靜态檔案、模闆和其它功能。

第一步:藍圖的建立(藍圖的示例和Flask的執行個體參數一樣)

add.py

from flask import Blueprint,render_template

bp = Blueprint("bp", __name__,
                   template_folder="blueprint_temp",
                   static_folder="blueprint_static",
                   static_url_path="/static2")

@bp.route("/add")
def add():
    return render_template("add.html")
           

第二步:注冊藍圖:

from flask import  Flask
import add

app = Flask(\__name__)

app.register_blueprint(add.bp)

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

五、Flask裡面的擴充,相當于django中的中間件

1.before_request 再請求進入視圖函數之前作出處理 return None;before_request是順序執行

2.after_request 在請求結束視圖函數之後,傳回用戶端之前 ,要有參數和傳回值,after_request是逆向執行

3.errorheadler(404) 自定制錯誤提示,自定義的函數必須有參數

  • before_request和after_request裝飾器的使用
from flask import Flask, request, render_template, redirect, Markup, session, url_for

app = Flask(__name__)
app.secret_key = "abcdefghijklmn"


@app.before_request
def process_request1():
    print('process_request1')


@app.after_request
def process_response1(response):  # 必須有參數
    print('process_response1')
    return response  # 必須有傳回值


@app.before_request
def process_request2():
    print('process_request2')


@app.after_request
def process_response2(response):  # 必須有參數
    print('process_response2')
    return response  # 必須有傳回值


@app.route("/login", methods=("GET", "POST"))
def login():
    if request.method == "GET":
        return render_template("login.html")
    if request.method == "POST":
        username = request.form.get("username")
        session["user"] = username
        return "登陸成功"

app.run()
           

通路login視圖函數後的控制台輸出結果為:

process_request1
process_request2
process_response2
process_response1
           

通過代碼的列印結果可以看出,before_request順序執行;after_request逆向執行

  • errorhandler(404)的使用
@app.errorhandler(404)
def errors(code_or_exception):   //必須有參數
    return "錯誤"    //可以傳回字元串,html,重定向等
           

六、閃現:flash

session存在在服務端的一個字典裡面,session儲存起來,取一次裡面還是有的,直到你删除之後才沒有了。

flash的本質:flash是基于session建立的,flash支援往裡邊放值,隻要你取一下就沒有了,相當于pop了一下。不僅吧值取走,而且吧session裡的東西去掉。

flash的使用:get_flashed_messages()和flash("内容")

from flask import Flask,session,render_template,request,flash,get_flashed_messages
import flask_config

app = Flask(__name__) 

@app.route("/index")
def index():
    res = get_flashed_messages()
    if not res:
        res = [""]
    flash("你剛才通路了index")
    return render_template("index.html",msg=res[0])

@app.route("/home")
def index1():
    res = get_flashed_messages()
    if not res:
        res = [""]
    flash("你剛才通路了home")
    return render_template("index.html",msg=res[0])

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

七、Flask的send_file使用

from flask import Flask,send_file

app = Flask(__name__)

@app.route("/index", endpoint="index")
def index():
     return send_file(file_path)   //send_file()的作用是打開檔案傳輸内容

app.run()
           

八、Flask的jsonify的使用

  • json.dumps的作用是序列化資料
  • jsonify的作用是将後端資料json序列化,打包一個 content-Type:application/json 傳回給用戶端
from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/index", endpoint="index")
def index():
     #return json.dumps({123:"34"})   //傳給前端的是json資料,僅此而已!
     return jsonify({123:"34"}))    //序列化資料,将響應頭的content-Type: 更改為application/json 
app.run()