[04] [Flask 快速上手笔记] 03. 路由

基本路由

使用 route() 装饰器来把函数绑定到 url,就可以定义不同的路径执行的内容

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello():
    return 'Hello, Flask'

@app.route('/about/')
def hello():
    return 'about Flask'

如果我们在路由的 url 设定中,尾巴加上斜线/
再造访没有斜线的网址的时候,例如 http://127.0.0.1:5000/about
会重新导向到有斜线的网址下:http://127.0.0.1:5000/about/
但若是网址带上斜线造访了尾部没有设定斜线的网址:http://127.0.0.1:5000/hello/
这个时候会得到一个404 Not Found

路由参数传递

如同所有路由一样,我们可以定义路由网址接收参数
在刚刚的 hello.py 中加入以下内容

from markupsafe import escape

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return f'User {escape(username)}'

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return f'Post {post_id}'

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return f'Subpath {escape(subpath)}'

防止注入攻击

首先要引用 escape 套件
为了防止使用者提交指令造成注入攻击,大多数的网页模版都会在渲染画面前将符号转译
透过 escape() 我们可以手动进行这件事情

传递网址参数

透过把 URL 的一部分标记为<variable_name> 就可以在 URL 中添加变数
标记的部分会作为关键字参数传递给函数

定义网址参数型别

通过使用<converter:variable_name>,可以选择性的加上一个验证,限制参数的型别

有以下几种类型:

转换器名称 说明
string 预设值,接受不含斜杠的文字
int 接受正整数
float 接受正浮点数
path 类似於 string 但是可以有斜杠
uuid 接受 UUID 字串

如此应该就看得懂我们上面的路由规则在做什麽了!

格式化字串文字

另外要提的是那个f到底是做什麽用的?其实就是我们在其他语言常用的%啦
学名叫做 Formatted String Literals,或是简称为 f-string

可以在官方文件中了解详细使用方法:f-strings

基本上来说就是将大括号内的变数值塞进去,而不是印出变数名称本身
而 f-strings 本身也具有格式设定的功能(format specifier)
这个选择性的参数可以定义 f-strings 的回传格式,如下方范例中将 pi 舍入到小数点後三位

>>> import math
>>> print(f'The value of pi is approximately {math.pi:.3f}')
The value of pi is approximately 3.142

现在我们除了 f-word 之外,还学会了 f-string 呢

动态路由构建

上面我们已经知道怎麽建置基本的路由,但是都是写死的
一但路由规则有所改变,那就必须对整个专案搜寻并修改路由
听起来超可怕的!

在 flask 有个方式解决这个问题,就是透过url_for
这是一个 flask 内建的函数,可以直接从 flask 导入

from flask import url_for

url_for()函数用於构建指定函数的 URL
把函数名称作为第一个参数,可以接受任意个关键字参数
每个关键字参数对应 URL 中的变数,并添加到 URL 中作为查询参数

底下就来示范这边的使用方法

from flask import Flask, url_for

app = Flask(__name__)

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

@app.route('/login-route')
def login():
    return 'login'

@app.route('/user/<username>')
def profile(username):
    return f'{username}\'s profile'

@app.route('/test/login')
def test_login():
    return url_for('login')

@app.route('/test/profile')
def test_profile():
    return url_for('profile', username='Jone Doe')

当我们造访/test/login 页面的时候,藉由url_for方法
会找到前面定义的函数「login()」并且用它来建构路由
在这边我们直接印出来就是定义好的 login 页面的「网址路由」
不是重新到导向到该路由,也不是执行函数内容!

另一方面,当我们造访/test/profile页面时,在 url_for 中加入参数
首先是找到「profile()」函数,并且将参数的内容填入指定函数的同名变数中

再说一次 url_for 是产生「网址路由」,不是执行函数,也不是重新导向!


<<:  TCP/IP vs OSI,网际网路中的协议模型

>>:  h1~h6标题基础用法

Vue.js指令(v-on)绑定(DAY29)

v-on (事件绑定) v-on是用来绑定event事件的指令,就像之前javascript介绍过...

Apple Developer 凭证与Provisioning Profile更新

App的效期一直是App开发者必须要面对的问题之一,来看看我做的小笔记~~ Apple开发者帐号登入...

Day04-CRUD API 实作(四)Model、Migration

大家好~ 今天要开始实作留言功能, 个人习惯先从建立 Model 开始, 在建立 Model 时, ...

EP 23: SQLite DB in Android and iOS for TopStore App

Hello, 各位 iT邦帮忙 的粉丝们大家好~~~ 本篇是 Re: 从零开始用 Xamarin 技...

日月千禧酒店 Soluna - All Day Dining 飨乐全日餐厅 - 午餐 Buffet at Millennium Hotel Taichung

我还是对日月千禧恢复供应「龙虾吃到饱」充满着期待... 第一次走进日月千禧,已经是好几年前的事情了,...