文章目录
1. 多url的使用
多路由
- 1个视图函数可以绑定多个路由关系
@app.route('/index')
@app.route('/')
def index():
return 'index'
# 打印路由表
print(app.url_map)
>console
Map([<Rule '/index' (OPTIONS, GET, HEAD) -> index>,
<Rule '/' (OPTIONS, GET, HEAD) -> index>,
<Rule '/static/<filename>' (OPTIONS, GET, HEAD) -> static>])
路由装饰器技巧
- 装饰器视图函数应该放在最外层,否则里面的装饰器不会生效
@decorater # 无效
@app.route('/')
@decorater # 有效
def index():
# if name:
# return name
return 'no name'
- 视图函数包裹的装饰器不能return其他值,否则会被包装成返回函数
def decorater(func):
def wrapper(*args, **kwargs):
import time
print(time.time())
return func(*args, **kwargs) # 视图函数装饰器仅能返回视图函数功能
return wrapper
/*/
与/*
的区别
- @app.route(’/index/’), 使用/index路径访问时,重定向到/index/,使用/index/正常访问
- @app.route(’/index’), 使用/index路径访问时,正常访问,使用/index/访问报错404
- 访问计数
from flask import Flask
app = Flask(__name__)
def count(f):
app.config['num'] = 0
def wrapper(*args, **kwargs):
app.config['num'] += 1
print(app.config['num'])
return f(*args, **kwargs)
return wrapper
@app.route('/')
@count
def index():
return 'index'
if __name__ == '__main__':
app.run(debug=True)
2. 动态路由参数
动态参数
指定不同的参数来加载不同的数据
@app.route('/house/<content>')
def house_detail(content):
return '您请求的房源信息是:%s' % content
* 参数需要放在两个尖括号中间 <>
* 视图函数中需要放和url中参数同名的参数
参数类型
- str(默认), 不能包含‘/’
- int
- float
- path,可以包含‘/’
- uuid
# int 参数
@app.route('/house/<int:house_id>')
def house_detail(house_id):
return '您请求的房源编号是:%d' % house_id
# path 参数
@app.route('/getpath/<path:url_path>/')
def hello_path(url_path):
return 'path: %s' % url_path
# uuid 参数
@app.route('/getuuid/')
def get_uuid():
a = uuid.uuid4()
return str(a)
正则路由转换器
- 匹配2-8位大小写字母及数字
- 作用:拓展路由支持的参数类型
- 配置: 正则转换器可在项目或应用初始化文件中定义,并全局使用
- 访问:127.0.0.1:5000/user/sssll12
#coding:utf-8
from flask import Flask
from werkzeug.routing import BaseConverter
#定义正则转换器的类
class RegexConverter(BaseConverter):
def __init__(self,url_map,*items):
super(RegexConverter, self).__init__(url_map)
self.regex=items[0]
app = Flask(__name__)
#实例化
app.url_map.converters['regex']=RegexConverter
@app.route('/user/<regex("([a-z]|[A-Z]|[0-9]){2,8}"):username>', methods=['POST', 'GET'])
def user(username):
return 'Hello,%s' % username
if __name__ == '__main__':
app.run(debug=True)
3. route()参数
methods
- 定义请求方法,默认GET
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
do_the_login()
else:
show_the_login_form()
redirect_to
- 永久重定向(访问/index时重定向到/hello)
@app.route('/index', redirect_to='hello')
def index():
return 'index'
@app.route('/hello')
def hello():
return 'hello'
endpoint
- 端点
- 通常用于“反向查找”
- 带endpoint参数
@app.route('/test')
def test():
pass
@app.route('/')
def hello_world():
return 'Hello World!'
print(app.view_functions)
print(app.url_map)
{'static': <bound method _PackageBoundObject.send_static_file of <Flask 'demo'>>,
'test': <function test at 0x7fef146cb430>,
'hello_world': <function hello_world at 0x7fef146d5790>}
Map([<Rule '/test' (OPTIONS, HEAD, GET) -> test>,
<Rule '/' (OPTIONS, HEAD, GET) -> hello_world>,
<Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
- 带endpoint参数
@app.route('/test', endpoint='Test')
def test():
pass
@app.route('/', endpoint='index')
def hello_world():
return 'Hello World!'
print(app.view_functions)
print(app.url_map)
{'static': <bound method _PackageBoundObject.send_static_file of <Flask 'demo'>>,
'Test': <function test at 0x7fb7adf8c3a0>,
'index': <function hello_world at 0x7fb7adf96700>}
Map([<Rule '/test' (GET, HEAD, OPTIONS) -> Test>,
<Rule '/' (GET, HEAD, OPTIONS) -> index>,
<Rule '/static/<filename>' (GET, HEAD, OPTIONS) -> static>])
- 对比
- 最初的理解: 路由访问路径与函数直接绑定,访问路由时直接找到对应的处理函数即可
- 正确的理解:endpoint做为路由访问路径与函数的中间桥梁存在,即:
访问路径<===>endpoint<===>视图函数
,访问时在路由表中通过路径找到对应绑定的endpoint,在视图表中根据endpoint找到对应的视图函数
defaults
- 动态参数漏传容错处理
@app.route('/hello/', defaults={'id': None})
@app.route('/hello/<id>')
def hello(id):
return f'hello {id}'
@app.route('/hello/')
@app.route('/hello/<id>')
def hello(id=None):
return f'hello {id}'