日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

flask框架总结

發(fā)布時間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 flask框架总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • flask框架總結(jié)
    • 原理
      • 請求上下文原理
      • flask握手原理
      • flask發(fā)送數(shù)據(jù)加密,解密原理
    • 快速啟動flask服務(wù)
      • app.run()接受參數(shù)如下
      • app.route()裝飾器接受參數(shù)如下
    • 動態(tài)路由參數(shù)
    • 處理請求方法
      • FBV 方法示例
      • CBV方法示例
    • flask響應(yīng)三劍客
    • reqeust
    • 模板語法jinja2
      • for語法
      • if語法
      • safe過濾器
      • Markup
      • 傳入函數(shù)名
      • 自定義標(biāo)簽
      • 自定義過濾器
      • extends標(biāo)簽
      • include標(biāo)簽
      • include和extend區(qū)別
      • 宏指令
    • session
    • flask配置
      • app配置
      • 初始化配置
    • flask藍圖
    • flask中間件
      • 自定義錯誤errorhandler
      • flask中flash閃現(xiàn)

flask框架總結(jié)

特點:短小精悍,支持三方組件,穩(wěn)定性相對其他框架較差。
web服務(wù)端,基于socket制作

原理


wsgi:應(yīng)用程序網(wǎng)關(guān)接口
django使用的是uwsgi
flask使用的是werkzeug(wsgi封裝)

請求上下文原理

在flask中reqeust和session都為公共變量,直接通過flask導(dǎo)入,而不是通過參數(shù)傳入視圖函數(shù)
實現(xiàn)原理是:
wsgi處理-》打包成ctx=RequestContext(包含reqeust,session)->ctx.push(將當(dāng)前請求信息存入棧中)-》視圖函數(shù)處理-》執(zhí)行reqeust相關(guān)方法時,從棧中獲取數(shù)據(jù)
{__storage__:{線程號:{"stack":[ctx]}},__ident_func__:get_ident}
get_ident為獲取線程號的方法名

flask握手原理

websocket通信原理
后端
獲取請求體中字符串Sec-WebSocket-Key,拿到key
用magic_string字符串與其拼接,使用sha1加密,再用base64加密
拼接響應(yīng)頭,添加Sec-WebSocket-Accept字段,發(fā)送給瀏覽器
前端瀏覽器
鏈接服務(wù)器,發(fā)送請求頭,含Sec-WebSocket-Key字段
獲取響應(yīng)頭,解密,校驗握手是否成功

flask發(fā)送數(shù)據(jù)加密,解密原理

解密
瀏覽器send發(fā)送數(shù)據(jù)過來為bytes類型

  • 第1位,固定\x81
  • 第2位, 首先與127進行與運算 有0得0 data_length結(jié)果有3種情況
    情況一: <= 125 當(dāng)前data_length就為數(shù)據(jù)長度 125(3-6為mask_key)
    情況二:==126 數(shù)據(jù)長度兩位,3-4字節(jié)為數(shù)據(jù)長度 65535(5-8mask_key)
    情況三:==127 數(shù)據(jù)長度為八位,3-10字節(jié)為數(shù)據(jù)長度 2**64(11-14mask_key)
  • 往后四位,為mask—key,為密鑰,可以解密后面的字符串
    bytes = decode[i] ^ mask[i%4]
    每位用或運算和mask—key的四個數(shù)
  • 加密

  • 解碼msg為bytes類型
  • 第一位固定為\x81
  • 計算程度,根據(jù)長度不同,打包的數(shù)據(jù)大小不同
    struct打包
    情況一: < 126 struct.pack("B",length)
    情況二: == 126 struct.pack("!BH",126,length)
    情況三: > 126 struct.pack("!BQ",127,length)
  • 拼接發(fā)送
  • 快速啟動flask服務(wù)

    from flask import Flaskapp = Flask(__name__) #在該模塊中Flask標(biāo)識,可以傳入任意字符串@app.route('/') #裝飾器第一個參數(shù)為路由 def index():return "hello world" # 直接返回字符串到頁面上app.run() # 啟動flask

    app.run()接受參數(shù)如下

    run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
    例如:
    app.run(host="127.0.0.1",port=9527,debug=True)
    debug為true時,每次修改代碼后,自動重啟服務(wù)

    app.route()裝飾器接受參數(shù)如下

    @app.route('/hi2',endpoint="hi2",redirect_to="/",methods=("GET","POST"),defaults={"age":22}) def hi2(age):return redirect('/')

    endpoint:函數(shù)標(biāo)識,默認為函數(shù)名,在反向解析時使用url_for(‘hi2’)可以解析出url。 當(dāng)函數(shù)重名時,只要endpoint不重名即可
    redirect_to:不通過視圖函數(shù),直接重定向(永久重定向)
    methods:允許請求方法,默認只允許GET,可以傳入一個列表或元組
    defaults:默認參數(shù),默認傳入視圖函數(shù)的參數(shù),視圖函數(shù)必須要有參數(shù)來接受
    strict_slashes:嚴格匹配,默認值為False,值為True時,地址末尾多一個斜杠也不允許訪問

    動態(tài)路由參數(shù)

    可以使用<>方式添加變量名,同時視圖函數(shù)也要接受參數(shù),來匹配路由
    <a> <int:b> <string:c>
    默認參數(shù)類型是字符串

    @app.route('/hi/<normal>/<int:age>') def hi(normal,age):print(normal,age)return redirect('/')

    處理請求方法

    處理請求有CBV和FBV兩種方式
    FBV:在視圖中,通過函數(shù)類處理請求
    CBV:在視圖中,通過類來處理請求

    FBV 方法示例

    通常我們使用函數(shù)加裝飾器方法組成視圖函數(shù)

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

    等價于

    def index2():return "hello world1" app.add_url_rule("/index2",view_func=index2)

    view_func為視圖函數(shù)的函數(shù)名

    CBV方法示例

    from flask import viewsdef war(func):def inner(*args,**argv):print("inner")return func(*args,**argv)return innerclass Index3(views.MethodView):methods = ["GET","POST"]decorators = [war]def get(self):return "nice get"def post(self):return "nice post" app.add_url_rule(rule="/test",view_func=Index3.as_view(name="index33"))

    類需要繼承views.MethodView,類中添加相應(yīng)請求方法的處理函數(shù)(get方法請求,就添加名為get的函數(shù))
    methods:默認為只允許get方法訪問
    decorators: 將類中每個函數(shù)添加裝飾器,每次執(zhí)行函數(shù)時,自動依次執(zhí)行裝飾器
    as_view:將類轉(zhuǎn)換為相應(yīng)視圖函數(shù),name為函數(shù)標(biāo)識

    flask響應(yīng)三劍客

    from flask import Flask,render_template,redirect,jsonify,send_file @app.route('/') def index():return "hello world"@app.route("/login") def login():return render_template('login.html')@app.route('/hi') def hi():return redirect('/')@app.route("/hello") def hello():return jsonify({"name":"xiaoming","age":16})@app.route("/web") def web():return send_file("./small.png")

    直接返回字符串,類似于django的HttpResponse
    render_template返回模板,類似于django的render
    redirect重定向(默認302臨時重定向),和django一樣

    jsonify返回json字符串,content-Type為Content-Type: application/json
    send_file返回一個本地文件,根據(jù)文件不同content-Type不同

    reqeust

    reqeust為一個全局變量,獲取請求信息,所有請求信息經(jīng)過wsgi處理后轉(zhuǎn)換為鍵值對形式存入字典中

    from flask import request @app.route('/') def index():print(request.method) #返回當(dāng)前請求方法print(request.args) #get攜帶的參數(shù)鍵值對(字典),get取值print(request.form) #表單提交<form>的結(jié)果(字典),get取值print(request.json) #數(shù)據(jù)格式application/json bytes類型print(request.data) #request定義的格式不存在的 application/xiaowangba bytes類型的數(shù)組 print(request.values) #同時獲得url攜帶參數(shù)和post請求獲取的參數(shù),get取值如果get和post請求參數(shù)重名時,取get請求參數(shù)的值因為先序列化form,后序列化args,args同名參數(shù)會將其覆蓋return "hello world"

    request還有url,path等方法

    模板語法jinja2

    在django和flask中都使用了jinja2語法
    變量語法 {{ msg }}
    tag標(biāo)簽語法 邏輯代碼 {% if %}

    for語法

    遍歷

    {% for stu in stu_list %} {% endfor %}

    獲取字典值時,可以使用下標(biāo),[],get方法

    <td>{{ student.name }}</td> <td>{{ student["name"] }}</td> <td>{{ student.get("name") }}</td>

    獲取列表值時,可以使用下標(biāo)方法或傳入索引

    <td>{{ student[0] }}</td><td>{{ student.0 }}</td>

    if語法

    條件判斷

    {% if session %} {% elif session1 %} {% else %} {% endif %}

    示例

    {% if student.3 == 'female' %}<input class="form-check-input" type="radio" name="sex" id="female" value="female" checked> {% else %}<input class="form-check-input" type="radio" name="sex" id="female" value="female"> {% endif %}

    safe過濾器

    將變量中字符串渲染成標(biāo)簽
    {{ msg|safe }}
    默認情況,字符串不能直接被渲染成字符串,必須使用safe過濾器

    Markup

    類似于safe,只不是在后端執(zhí)行

    from flask import Markup @app.route('/1') def index1():text_tag = "<p>我是p標(biāo)簽</p>"text_tag = Markup(text_tag)return render_template("index.html",msg=text_tag)

    將字符串轉(zhuǎn)換為標(biāo)簽,在頁面上渲染

    傳入函數(shù)名

    后端也可以直接向前端傳入函數(shù)名,前進接受后直接使用
    python

    def add(a,b):return a+b@app.route('/2') def index2():return render_template("index.html",add=add)

    html

    {{ add(1,2) }}

    自定義標(biāo)簽

    自定義全局函數(shù)
    python

    @app.template_global() def add_tag(*args):return sum(*args)

    不需要通過參數(shù)傳入模板,直接在模板中調(diào)用
    html

    {{ add_tag([1,2,3]) }}

    自定義過濾器

    自定義全局過濾器
    python

    @app.template_filter() def jiou(num):return "奇數(shù)" if num % 2 else "偶數(shù)"

    html

    {{ 5|jiou }}

    extends標(biāo)簽

    繼承父模板框架,必須卸載最上方
    block:在index.html中為占位符,在index2.html中為實際內(nèi)容
    index.html

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> {% block container %}<p>默認顯示內(nèi)容,沒有block時顯示</p> {% endblock %} </body> </html>

    index2.html

    {% extends "index.html" %} {% block container %}<p>新內(nèi)容</p> {% endblock %}1

    include標(biāo)簽

    include:導(dǎo)入代碼塊,將代碼塊導(dǎo)入到網(wǎng)頁中
    index.html

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> {% include "login.html" %}</body> </html>

    login.html

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>登錄</title> </head> <body> 登錄 </body> </html>

    include和extend區(qū)別

    include:用于多個html頁面,有相同代碼部分,這部分用include導(dǎo)入,比如導(dǎo)入小廣告
    extends:用戶同一主題的頁面,用相同主題,只修改block部分,其他部分不變。extends必須寫在頁面開頭,配合block使用。模板繼承

    宏指令

    創(chuàng)建標(biāo)簽,宏指令

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>登錄</title> </head> <body> 登錄 {% macro create_tag(name) %}<p>{{ name }}</p> {% endmacro %}{{ create_tag("xiaoming") }} {{ create_tag("wanghua") }}</body> </html>

    相當(dāng)于html中的函數(shù),傳入?yún)?shù),執(zhí)行參數(shù)

    session

    session和cookie用戶信息的緩存,cookie一般存放在用戶端,session一般存放在服務(wù)端
    但是flask原生session是將用戶信息存放在cookie中,也就是用戶端

    from flask import sessionapp = Flask(__name__) app.secret_key = "this_is_any_string" @app.route('/3') def index3():session["name"] = "xiaoming" #添加一個session鍵值對print(session["name"]) #獲取session值return render_template("test.html")

    注意:首先導(dǎo)入session,其次必須要secret_key
    session存放在cookie中,鍵session,值(secret_key經(jīng)過md5序列化+時間戳+session字典中的鍵值)

    flask配置

    app配置

    方法一:
    使用字典方式設(shè)置

    from flask import Flask app = Flask(__name__) app.config["DEBUG"]=True

    方法二:
    使用對象方式

    obj為類 class obj():DEBUG:TrueSECERT_KEY="1234567890" app.config.from_object(obj)

    在對象中設(shè)置值

    初始化配置

    flask示例初始化配置

    app = Flask(__name__) ''' def __init__(self,import_name, #該參數(shù)用來標(biāo)識實例的(用來區(qū)分是否是一個實例化對象,request等)static_url_path=None, #訪問靜態(tài)文件的url 默認等于static_folderstatic_folder="static", #靜態(tài)文件夾static_host=None, #遠程訪問靜態(tài)文件(靜態(tài)文件夾不在本地)必須和host_matching一起用host_matching=False,subdomain_matching=False,template_folder="templates", #指定模板文件夾instance_path=None,instance_relative_config=False,root_path=None, ): '''

    flask藍圖

    flask藍圖相當(dāng)于不能運行的flask實例,用來做插件用
    student_add.py

    from flask import Blueprint stu_add = Blueprint("stu_add",__name__) @stu_add.route("/student_add",methods=("GET",'POST')) def student_add():return render_template("student_add.html")

    參數(shù)一位藍圖實例名,用來區(qū)分藍圖與藍圖
    參數(shù)二藍圖空間標(biāo)識
    注意:藍圖默認static和template和app默認存儲位置相同

    注冊藍圖
    main.py

    from student_add import stu_add app.register_blueprint(stu_add.stu_add)

    即可使用
    藍圖中的視圖函數(shù)名與app視圖函數(shù)名相同時不會出錯,但url_for反向解析時會報錯

    flask中間件

    flask使用兩種裝飾器類似于django中的中間件

    @app.before_request def is_login():white_list = ['/login',]if request.path in white_list:return Noneif session.get("is_login") and session["is_login"] + 3000*60 > time.time():return Noneelse:return redirect('/login')@app.after_request def go(res):print("after")return res
  • before_request在每次進入任何視圖函數(shù)前使用,after_request在每次出視圖函數(shù)前使用 2. after_request必須傳入一個參數(shù)response,返回這個參數(shù)
  • before_request執(zhí)行順序,代碼順序before1->before2,在請求進入視圖函數(shù)之前作出處理
  • after_request執(zhí)行順序,從后向先執(zhí)行 after2->after1 代碼在前面的,執(zhí)行順序靠后
  • 正常執(zhí)行順序:before1->before2->after2->after1
  • 當(dāng)before2出現(xiàn)異常時,before1->after2->after1
  • 自定義錯誤errorhandler

    可以自定義404錯誤

    @app.errorhandler(404) def errors(*args):print(args)return "沒有找到當(dāng)前頁面"

    也可以自定義錯誤頁面

    flask中flash閃現(xiàn)

    flash存一次,取一次后就銷毀,不占空間。
    通常用來上一個位置使用

    from flask import flash,get_flashed_messages@app.route("/home") def home():res = get_flashed_messages()print(res)flash("home")return render_template("home.html",loc = res)@app.route("/music") def music():res = get_flashed_messages()print(res)flash("music")return render_template("music.html",loc = res)

    總結(jié)

    以上是生活随笔為你收集整理的flask框架总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。