1. 程式人生 > >flask基礎2

flask基礎2

一個裝飾器無法裝飾多個函式的解決方法

當我們想在flask的多個檢視函式前新增同一個裝飾器時,如果什麼都不做會報一個錯

AssertionError: View function mapping is overwriting an existing endpoint function: nei

 

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

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


def wai(func):
    
def nei(*args, **kwargs): if session.get("user"): ret = func(*args,**kwargs) return ret else: return redirect("/login") return nei @app.route("/") @wai def index(): return render_template("index2.html") @app.route("/qqq") @wai def qqq():
return render_template("qqq.html") @app.route("/login", methods=["POST", "GET"]) def login(): if request.method == "GET": return render_template("login.html") else: if request.form.get("username") == "12345" and request.form.get("password") == "12345": session["user
"] = request.form.get("username") return "登入成功" app.run(debug=True)

 

  會報上面的錯,原因是用裝飾器去裝飾函式時返回的是nei這個函式,也就是有兩個nei函式,所以報錯

解決方案1

import functools #引入一個函式工具

def wai(func):
    @functools.wraps(func) #加上這句就會保留原來的函式名
    def nei(*args, **kwargs):
        if session.get("user"):
            ret = func(*args,**kwargs)
            return ret
        else:
            return redirect("/login")
    return nei

解決方案2

因為是flask檢視函式,所以它為我們準備了一個引數endpoint 它反向生成url地址標誌,預設檢視函式名

@app.route("/", endpoint="index")
@app.route("/qqq", endpoint="qqq")

1.flask中的路由

1.endpoint 反向生成url地址標誌 預設檢視函式名 可以from flask import url_for url_for("")

2.methods 檢視函式允許的請求方式

@app.route("/login", methods=["GET", "POST"]) #預設下面的函式只有get請求,一旦添加了methods引數就會按照新增的請求方式處理,後面是一個可迭代物件列表或元組

3.動態路由引數

@app.route("/login/<string:nid>", methods=["GET", "POST"], strict_slashes=False) #<string:nid>只有string或int型別,不寫就是string 有動態路由引數下面的函式必須接受引數
def index2(nid):
    print(url_for("index2"))
    print(nid)
    return "456"

4.defaults={"nid":"123456"} 預設引數

5.strict_slashes=True 是否嚴格遵循路由地址 不寫就是false

6.redirect_to="/login" 永久重定向 301   #進入檢視之前

2.flask例項化配置

app = Flask(__name__, template_folder="templates", static_folder="static", static_url_path="/static")
1.template_folder="temp" 預設模板路徑 templates
2.static_folder="static", 預設靜態檔案路徑 static
3.static_url_path="/static" 訪問靜態檔案路由地址 預設是"/"+static_folder

4.static_host=None 指定靜態檔案伺服器地址
5.host_matching = False,  # 如果不是特別需要的話,慎用,否則所有的route 都需要host=""的引數
6.subdomain_matching = False,  # 理論上來說是用來限制SERVER_NAME子域名的,但是目前還沒有感覺出來區別在哪裡
7.instance_path = None,  # 指向另一個Flask例項的路徑
8.instance_relative_config = False  # 是否載入另一個例項的配置
9.root_path = None  # 主模組所在的目錄的絕對路徑,預設專案目錄

3.flask物件配置

'DEBUG': False,  # 是否開啟Debug模式
'TESTING': False,  # 是否開啟測試模式
'SECRET_KEY': None # 在啟用Flask內建Session的時候/開啟flash,一定要有它
'PERMANENT_SESSION_LIFETIME': 31,  # days , Session的生命週期(天)預設31天
'SESSION_COOKIE_NAME': 'session',  # 在cookies中存放session加密字串的名字
#配置方式1
app.config["DEBUG"] = True
#配置方式2
FlaskSetting.py
--------------------------------------
class FlaskDebug(object):
    DEBUG = True
    SECRET_KEY = "LIANNDA"
    PERMANENT_SESSION_LIFETIME = 7
    SESSION_COOKIE_NAME = "debug_session"

class FlaskTesting(object):
    DEBUG = True
    SECRET_KEY = "LIANNDA"
    PERMANENT_SESSION_LIFETIME = 15
    SESSION_COOKIE_NAME = "test_session"
----------------------------------------------------------------


import FlaskSetting app.config.from_object(FlaskSetting.FlaskDebug) app.config.from_object(FlaskSetting.FlaskTesting)

4.flask藍圖(藍圖配置)

Blueprint 當成一個不能被啟動的 app Flask示例

# 藍圖配置
from flask import Blueprint, render_template

s4app = Blueprint("s4app", __name__, template_folder="apptemp", url_prefix="/lantu")  #前三個引數必須給,後一個可選,如果添加了在訪問時/lantu/s4app

@s4app.route("/s4app")
def s4appa():          # 藍圖例項名不要與函式名重複
    return render_template("s4app.html")  
#在flask例項上註冊藍圖,才能訪問
from user_reg import views
app.register_blueprint(views.s4app)

5.flask中的特殊裝飾器

@app.before_request # 請求進入檢視函式之前

@app.after_request # 響應返回客戶端之前

如果有多個before_request按從上到下執行,多個after_request按從下到上執行

正常情況下流程:be1 - be2 - be3 - af3 - af2 - af1
異常情況下流程:be1 - af3 - af2 - af1

@app.before_request
def be1():
    if request.path == "/login":
        return None
    if not session.get("user"):
        return redirect("/login")

@app.after_request
def af1(response):
    return response

@app.errorhandler(404) # 重定義錯誤頁面返回資訊

@app.errorhandler(404) #填錯誤碼
def error404(error):   #接收引數為錯誤資訊
    return render_template("my_error.html")