4、Flask實戰第4天:自定義url轉換器


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,
}
View Code

通過源碼,我們知道這些就是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)


免責聲明!

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



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