1. 程式人生 > >Flask中正則匹配路由及路由轉換器

Flask中正則匹配路由及路由轉換器

正則匹配路由

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

具體實現步驟為:

  • 匯入轉換器基類(BaseConverter):在 Flask 中,所有的路由的匹配規則都是使用轉換器物件進行記錄
  • 自定義轉換器:自定義類繼承於轉換器基類
  • 將自己的轉換器新增到預設的轉換器列表中
  • 使用自定義轉換器實現自定義匹配規則

路由轉換器: 匹配URL路由規則的物件

具體程式碼實現

# 1. 匯入轉換器基類
from werkzeug.routing import
BaseConverter # 2. 自定義轉換器, 自定義類繼承於轉換器基類 class RegexConverter(BaseConverter): """自定義正則路由轉換器""" def __init__(self, url_map, *args): super(RegexConverter, self).__init__(url_map) #取到第一個引數,給regex屬性賦值 # regex ="\d{6}" #匹配6位數字 self.regex = args[0] # 3.將自己的轉換器新增到預設的轉換器列表中
app.url_map.converters['re'] = RegexConverter # 使用自定義的轉換器進行路由規則匹配, 轉換器規則自定義並以引數傳入 @app.route('/user/<re("[0-9]{4}"):user_id>') def user(user_id): return "獲取使用者的id是:%s"%user_id

自定義轉換器其他兩個函式實現

​ 繼承於自定義轉換器之後,還可以實現 to_python 和 to_url 這兩個函式去對匹配引數做進一步處理:

to_python

  • 該函式引數中的 value 值代表匹配到的值
    ,可輸出進行檢視
  • 轉換器匹配完成之後,對匹配到的引數作最後一步處理再返回,比如:轉成 int 型別的值再返回:
class RegexConverter(BaseConverter):
    def __init__(self, url_map, *args):
        super(RegexConverter, self).__init__(url_map)
        # 將接受的第1個引數當作匹配規則進行儲存
        self.regex = args[0]

    def to_python(self, value):
        return int(value)

執行測試,在檢視函式中可以檢視引數的型別,由之前預設的 str 已變成 int 型別的值

to_url:

  • 在使用 url_for 去獲取檢視函式所對應的 url 的時候,會呼叫此方法對 url_for 後面傳入的檢視函式引數做進一步處理
  • 具體可參見 Flask 的 app.py 中寫的示例程式碼:ListConverter
from flask import Flask
from flask import redirect
from flask import url_for
from werkzeug.routing import BaseConverter

class ListConverter(BaseConverter):
    """自定義轉換器"""
    regex = "(\\d+,?)+\\d$" # r"(\d+,?)+\d$" #匹配1,23,3,45這種模式的字串

    def to_python(self, value):
        """當匹配到引數之後, 對引數做進一步處理之後,再返回給檢視函式"""
        return value.split(',')

    def to_url(self, value):
        """
        在進行重定向使用url_for的時候,對檢視函式傳的引數進行處理,
        處理完畢之後以便能夠進行路由匹配
        """
        result = ','.join(str(v) for v in value)
        return result
    
app = Flask(__name__)
app.url_map.converters['list'] = ListConverter

@app.route('/users/<list:user_ids>')
def demo2(user_ids):
    return "接收到的ids是: %s"%user_ids

@app.route('/demo3')
def demo3():
    return redirect(url_for('demo2', user_ids=[1,2,3,4,5]))


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

說明: 當在瀏覽器中訪問"http://localhost:5000/demo3"將重定向到檢視函式demo2對應的路由,在此之前url_for函式的引數user_ids的引數會傳到自定義轉換器類to_url函式進行處理,處理完成後將result返回到demo2對應的路由轉換器list, 在進行轉換器規則校驗前將result結果再又傳入到ListConverter轉換器的to_python進行處理,處理後的結果交給demo2檢視函式進行返回;(注:整個過程可以通過pycharm斷點檢視);

系統自帶轉換器
DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}