url傳參可以限定參數的數據類型,例如:限定user_id數據類型為int
@app.route('/user/<int:user_id>') def my_list(user_id): return '您輸入的user_id為:{}'.format(user_id)
當我們傳遞的參數不是int類型的時候,頁面訪問該url就會返回404錯誤,我們可以來看下flask是如何定義這些數據類型的
首先導入BaseConverter
from werkzeug.routing import BaseConverter
按住ctrl用戶鼠標點擊BaseConverter進去查看源碼,可以發現BaseConverter是一個基類,下面很多子類繼承了它,這些子類是
UnicodeConverter
AnyConverter
PathConverter
NumberConverter
IntegerConverter
FloatConverter
UUIDConverter
往下看,可以看出這些都是默認的數據類型

#: the default converter mapping for the map. DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter, }
通過源碼,我們知道這些就是flask給我們定義的數據類型,這些子類都是繼承BaseConverter,然后利用正則來匹配
了解這些后,我們就可以自定義數據類型了
需求:一個url中,含有手機號碼的參數,必須限定這個參數滿足手機號碼的格式
from werkzeug.routing import BaseConverter ... class TelephoneConveter(BaseConverter): regex = r'1[3458]\d{9}' # 這里是定義數據類性的名字,並注冊到url_map中 app.url_map.converters['tel'] = TelephoneConveter #然后我們就可以使用自定一的tel類型了 @app.route('/my_tel/<tel:telephone>') def my_tel(telephone): return '您的手機號碼是:{}'.format(telephone)
to_python
這個方法的返回值,將會傳遞到view函數中作為參數
現在有個需求:訪問127.0.0.1/posts/a+b能夠顯示出a和b的所有帖子
根據需求,我們知道需要把參數a+b解析出來,並通過數據庫去查詢,這里不去討論數據庫這塊,只是來怎么分解a+b
@app.route('/posts/<boards>') def posts(boards): borads = boards.split('+') #borads現在是一個列表,很容易取出a,b的值 return str(borads)
上面的方法雖然可以實現,但是如果用到的類似場景較多的時候,我們還要再寫一遍,每次寫就比較麻煩,這時候我們就可以利用to_python來實現
class ListConveter(BaseConverter): def to_python(self, value): #這個value就是我們url的參數 return value.split("+") #這個返回值,就是我們視圖函數接收到的參數 app.url_map.converters['list'] = ListConveter @app.route('/posts/<list:boards>') def posts(boards): #這里的borads已經被list處理了,變成了列表 return str(borads)
to_url
這個方法的返回值,將會在調用url_for函數的時候生成符合要求的url形式
class ListConveter(BaseConverter): def to_python(self, value): return value.split("+") def to_url(self, value): return '+'.join(value) app.url_map.converters['list'] = ListConveter @app.route('/') def hello_world(): return url_for('posts', boards=['a', 'b']) @app.route('/posts/<list:boards>') def posts(boards): return str(boards)