二、Flask_路由定義與http的請求/響應


 

1. 路由定義

1.1 路由基本定義

...
# 指定訪問路徑為 demo
@app.route('/demo')
def demo():
    return 'demo'
...

1.2 路由傳遞參數(兩種)

  1. 沒有限定類型
    #
    @app.route('/user/<user_id>')
    def user_info(user_id):
        return 'hello %s' % user_id
  2. 限定數據類型
    #
    @app.route('/user/<int:user_id>')
    def user_info(user_id):
        return 'hello %d' % user_id

     

1.3 路由限定請求方式

#
@app.route('/demo', methods=['GET', 'POST'])
def demo():
    # 直接從請求中取到請求方式並返回
    return request.method

 

1.4 正則匹配路由

在 web 開發中,可能會出現限制用戶訪問規則的場景,那么這個時候就需要用到正則匹配,根據自己的規則去限定請求參數再進行訪問

具體實現步驟為:

  • 導入轉換器基類:在 Flask 中,所有的路由的匹配規則都是使用轉換器對象進行記錄

  • 自定義轉換器:自定義類繼承於轉換器基類

  • 添加轉換器到默認的轉換器字典中

  • 使用自定義轉換器實現自定義匹配規則

代碼實現

  1. 導入轉換器基類
    from werkzeug.routing import BaseConverter
  2. 自定義轉換器
    # 自定義正則轉換器
    from werkzeug.routing import BaseConverter
    class RegexConverter(BaseConverter):
        def __init__(self,url_map,*args):
            super(RegexConverter, self).__init__(url_map)
            # 正則參數
            self.regex = args[0]
  3. 添加轉換器到默認的轉換器字典中,並指定轉換器使用時名字為: re
    # 將自定義轉換器添加到轉換器字典中,並指定轉換器使用時名字為: re
    app.url_map.converters['re'] = RegexConverter
  4. 使用轉換器去實現自定義匹配規則
    # 當前此處定義的規則是:手機號碼
    
    # 正則匹配路由
    @app.route("/login/<re('1\d{10}'):mobile>")
    def login(mobile):
        return mobile

     

1.5 系統自動轉換器

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

系統自帶的轉換器具體使用方式在每種轉換器的注釋代碼中有寫,請留意每種轉換器初始化的參數。

 

2 http請求與響應

文檔:http://docs.jinkan.org/docs/flask/api.html#flask.request

2.1 請求

  • request:flask中代表當前請求的 request 對象

  • 作用:在視圖函數中取出本次請求數據

  • 導入:from flask import request

獲取方法

request.屬性

 

 常用的屬性如下:

屬性 說明 類型
data 記錄請求的數據,並轉換為字符串 *
form 記錄請求中的表單數據 MultiDict
args 記錄請求中的查詢參數 MultiDict
cookies 記錄請求中的cookie信息 Dict
headers 記錄請求中的請求頭 EnvironHeaders
method 記錄請求使用的HTTP方法 GET/POST
url 記錄請求的URL地址 string
files 記錄請求上傳的文件 *
json 記錄請求的json數據 json

 屬性下有屬性

使用方法 request.args.屬性(參數)  

屬性 說明 類型 舉例
get() 獲取一個參數的一個值   request.args.get("username")
getlist() 獲取一個參數的多個值 List request.args.getlist("love")
to_dict( ) 把傳遞過來的數據抓換成原生的字典 Dict request.args.to_dict()
to_list( )     request.headers.to_list()

 

 

from flask import Flask
# 新增一個配置文件,在配置文件中設置配置信息
from config import Config
from flask import request
# from collections import OrderedDict  # 有序字典

app = Flask(__name__)

# 調用app.config加載配置
app.config.from_object(Config)


from werkzeug.routing import BaseConverter

class RegexConverter(BaseConverter):
    def __init__(self,url_map,*args):
        super(RegexConverter, self).__init__(url_map)
        # 正則參數
        self.regex = args[0]

# converter["路由轉換器名稱"] = 實現路由轉換功能的自定義類
app.url_map.converters['re'] = RegexConverter
# 綁定路由
@app.route("/")
def index():
    return "hello flask"


# 默認情況下,路由使用的就是關鍵字參數,也叫"命名路由"
# router(路由地址, http請求方式 )
@app.route("/list/<int:page>/<string:content>",methods=["GET","POST"])
def mylist(content,page):
    return "第%s頁<br>內容:%s" % (page,content)

# 正則匹配路由
@app.route("/login/<re('1\d{10}'):mobile>")
def login(mobile):
    return mobile

"""獲取客戶端的請求"""
@app.route("/request")
def req1():
    """獲取查詢字符串"""
    query_string = request.args
    # print(query_string)
    """打印效果: ImmutableMultiDict([('username', 'xiaoming'), ('user_id', '1')])"""

    # 獲取一個參數的一個值
    username = request.args.get("username")
    # print(username)
    """打印效果: xiaoming"""

    # 獲取一個參數的多個值
    # http://www.luffycity.cn:5000/request?username=xiaoming&user_id=1&love=吹牛&love=睡覺
    love = request.args.getlist("love")
    # print(love)
    """打印效果: ['吹牛', '睡覺']"""


    # 把傳遞過來的數據抓換成原生的字典
    data = request.args.to_dict()
    # print(data)
    """打印效果: {'username': 'xiaoming', 'user_id': '1', 'love': '吹牛'} """

    return "ok"

@app.route("/request2",methods=["POST"])
def req2():
    """獲取post數據和請求頭"""
    # print( request.data )
    # """打印結果:
    # b'{\n\t"username":"xiaoming",\n\t"age":18,\n\t"sex":1\n}'
    # """
    #
    # import json
    # from flask import json
    # data = json.loads(request.data)
    # print(data)
    # """打印結果:
    # {'username': 'xiaoming', 'age': 18, 'sex': 1}
    #
    # """
    #
    # """獲取請求行數據"""
    # print( request.headers )
    # print( request.headers.to_list() )


    """獲取上傳文件"""
    print( request.files )
    print( request.files.get("avatar") )
    """打印效果: 
    ImmutableMultiDict([('avatar', <FileStorage: 'avatar.png' ('image/png')>)])
    <FileStorage: 'avatar.png' ('image/png')>
    """

    return "ok"

if __name__ == '__main__':
    app.run()
測試代碼

 

2.2 響應

flask默認支持2種響應方式:

  1. 數據響應: 默認響應html文本,也可以返回 JSON格式
  2. 頁面響應: 重定向(url_for)

響應的時候,flask也支持自定義http響應狀態碼

2.2.1 數據響應

響應html文本

@app.route("/")
def index():
    # [默認支持]響應html文本
    return "<img src='http://flask.pocoo.org/static/logo.png'>"

返回json格式

from flask import Flask, request, jsonify

@app.route("/")
def index():
    # 也可以響應json格式代碼
    data = [
        {"id":1,"username":"liulaoshi","age":18},
        {"id":2,"username":"liulaoshi","age":17},
        {"id":3,"username":"liulaoshi","age":16},
        {"id":4,"username":"liulaoshi","age":15},
    ]
    return jsonify(data)

 

2.2.2 重定向

重定向到外部網站

# 頁面跳轉響應
@app.route("/user")
def user():
    # 頁面跳轉 redirect函數就是response對象的頁面跳轉的封裝
    # Location: http://www.baidu.com
    return redirect("http://www.baidu.com")

 

重定向到視圖函數

  1. 可以直接填寫自己 url 路徑
  2. 使用url_for實現視圖方法之間的內部跳轉 url_for("視圖方法名") 
    from flask import redirect,url_for
    
    @app.route('/user/<user_id>')
    def user_info(user_id):
        return 'hello %d' % user_id
    
    @app.route("/index")
    def index():
        # 1. 跳轉到站內地址,例如其他頁面
        return redirect("/response")
        # 2.1 跳轉到站內視圖函數對應的頁面中[沒有附帶地址參數]
        return redirect(url_for("index"))
        # 2.2 跳轉到站內視圖函數對應的頁面中[有附帶地址參數,通過命名參數傳遞路由參數]
        return redirect(url_for('user_info', user_id=100))

     

2.2.3 自定義狀態碼

在 Flask 中,可以很方便的返回自定義狀態碼,以實現不符合 http 協議的狀態碼,例如:status code: 666

@app.route('/demo')
def demo():
    return '狀態碼為 666', 400

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM