一、 路由参数
路由是什么?
- 是一种绑定应用程序和url 地址的对应映射关系;在编辑项目时,往往完成一个功能的类就是一个路由类,简称路由
- 路由和视图的名称必须全局唯一,不能出现重复,否则报错。
路由的传递分类两种方式:
1 不限定类型传递路由参数
from flask import Flask
app = Flask(__name__)
# 不限定类型传递路由参数
@app.route("/collection/<collection_id>/<aritcle_id>")
def index(collection_id,aritcle_id):
return f"collection_id={collection_id}, aritcle_id={aritcle_id}"
# 加载项目配置
class Config(object):
DEBUG = True
app.config.from_object(Config)
if __name__ == '__main__':
# flask运行过程中,所有的路由最终都会被注册到url_map里面。
print( app.url_map )
app.run(host="0.0.0.0",port=5000)
2 限定类型传递路由参数
from flask import Flask
app = Flask(__name__)
# 限定类型传递路由参数
# flask内置的所有路由转换器是由werkzeug.routing的DEFAULT_CONVERTERS字典进行配置的。
# flask的所有路由转换器,本质上就是路由经过正则来进行匹配获取参数值的。所有的路由转换器都必须直接或间接继承于BaseConverter路由转换器基类
@app.route("/sms/<int(min=10,max=100):mobile>")
def sms(mobile):
return f"mobile={mobile}"
# 加载项目配置
class Config(object):
DEBUG = True
app.config.from_object(Config)
if __name__ == '__main__':
app.run(host="0.0.0.0",port=5000)
限定路由参数的类型,flask系统自带转换器编写在
werkzeug.routing.py文件中。底部可以看到以下字典:DEFAULT_CONVERTERS = { "default": UnicodeConverter, "string": UnicodeConverter, "any": AnyConverter, "path": PathConverter, "int": IntegerConverter, "float": FloatConverter, "uuid": UUIDConverter, # 接受UUID(通用唯一识别码)字符串 xxxx-xxxx-xxxxx-xxxxx }
二、 自定义路由转换器
实现步骤
- 导入转换器基类,在 flask 中,所有的路由规则都是通过转换器对象实现的
- 自定义转换器:父类为BaseConverter
- 添加转换器到默认的转换字典中
- 使用自定义转换器实现自定义匹配转换规则
from flask import Flask
app = Flask(__name__)
# 自定义路由转换器
from werkzeug.routing import BaseConverter
class RegexConverter(BaseConverter):
def __init__(self,map,*args):
super().__init__(map)
# 正则参数
self.regex = args[0]
# 将自定义转换器添加到转换器字典中,并指定转换器使用时名字为: re
app.url_map.converters['re'] = RegexConverter
# 正则匹配路由
@app.route("/sms/<re('1[3-9]\d{9}'):mobile>")
def sms(mobile):
return f"mobile={mobile}"
# 加载项目配置
class Config(object):
DEBUG = True
app.config.from_object(Config)
if __name__ == '__main__':
# flask运行过程中,所有的路由最终都会被注册到url_map里面。
print( app.url_map )
app.run(host="0.0.0.0",port=5000)
from werkzeug.routing import BaseConverter
class MobileConverter(BaseConverter):
"""手机号码类型限制"""
def __init__(self,map,*args):
super().__init__(map)
self.regex = "1[3-9]\d{9}"
# 把自定义转换器添加到flask默认的转换器字典中,也就是和原来的int,float等放在一块
app.url_map.converters['mob'] = MobileConverter # 字典哦
# 类似原来的路由参数限制一样,调用自定义转换器名称即可
@app.route(rule='/user/<mob:mobile>')
def user(mobile):
return mobile
# 1. 引入flask的路由转换器
from werkzeug.routing import BaseConverter
# 2. 创建自定义路由转换器
class RegexConverter(BaseConverter):
"""根据正则进行参数限制"""
def __init__(self,map,*args):
super().__init__(map)
self.regex = args[0]
# 3. 把自定义转换器添加到flask默认的转换器字典中,也就是和原来的int,float等放在一块
app.url_map.converters['re'] = RegexConverter
# 4. 类似原来的路由参数限制一样,调用自定义转换器名称即可
@app.route(rule='/user/<re("\w+@\w+\.\w+"):email>')
def user2(email):
print(app.url_map) # 获取所有的路由列表
return email
# 声明和加载配置
class Config():
DEBUG = True
app.config.from_object(Config)
if __name__ == '__main__':
# 运行flask
app.run(host="0.0.0.0")
三、限制 HTTP 请求
methods=["post","put","get","delete","patch"]
from flask import Flask,request
app = Flask(__name__)
# from flask.app import Request
@app.route("/", methods=["POST"])
def index():
print("request.method=%s" % request.method)
print("request.url=%s" % request.url)
print("request.query_string=%s" % request.query_string)
print("request.path=%s" % request.path)
return request.method
# 加载项目配置
class Config(object):
DEBUG = True
app.config.from_object(Config)
if __name__ == '__main__':
# flask运行过程中,所有的路由最终都会被注册到url_map里面。
print( app.url_map )
app.run(host="0.0.0.0",port=5000)
结果:
获取解析后的查询字符串
from flask import Flask,request
from urllib.parse import parse_qs
from werkzeug.datastructures import ImmutableMultiDict
app = Flask(__name__)
@app.route("/", methods=["POST"])
def index():
"""获取查询字符串"""
# 获取原生查询字符串query_string
# print( request.query_string )
# print( parse_qs( request.query_string.decode() ) )
"""POST 127.0.0.1:5000?username=xiaoming&pwd=123
b'username=xiaoming&pwd=123'
{'username': ['xiaoming'], 'pwd': ['123']}
"""
# 获取解析后的查询字符串
# print(request.args)
# print(request.args.get("username"))
# print(request.args.get("lve"))
# print(request.args.getlist("lve"))
"""POST /?username=xiaoming&pwd=123&lve=shoping&lve=game
ImmutableMultiDict([('username', 'xiaoming'), ('pwd', '123')]) # ImmutableMultiDict 是 一个有序字典,类似from collections import OrderedDict
xiaoming
shoping
['shoping', 'game']
"""
print(request.args.to_dict(flat=True))
print(request.args.to_dict(flat=False))
print(request.args)
"""POST 127.0.0.1:5000?username=xiaoming&pwd=123&lve=shoping&lve=game
{'username': 'xiaoming', 'pwd': '123', 'lve': 'shoping'}
{'username': ['xiaoming'], 'pwd': ['123'], 'lve': ['shoping', 'game']}
"""
return "hello"
@app.route(rule="/data",methods=["post","put","patch"])
def data():
"""接受客户端发送过来的原生请求体数据,是request.json,request.form,request.files等无法接受的数据,全部会保留到这里"""
print(request.data)
return "hello"
if __name__ == '__main__':
app.run(host="0.0.0.0",port=5000,debug=True)