Flask解析(二)路由(werkzeug.routing里 Map, Rule)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask解析(二)路由(werkzeug.routing里 Map, Rule)相关的知识,希望对你有一定的参考价值。
参考技术A 这章是跟着上一章讲的,如有不适应请点击 上一章
服务器里的路由是一个非常重要的角色,它控制了路径与视图函数的关联。
url的是统一资源定位符,对可以从 互联网 上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
常见的url是:122.227.20.190:8000/index
可以分成:
通俗的讲
Werkzeug 库的routing模块的主要功能在于URL解析。对于WSGI应用来讲,不同的URL对应不同的视图函数,routing模块则会对请求信息的URL进行解析并匹配,触发URL对应的视图函数,以此生成一个响应信息。routing模块的解析和匹配功能主要体现在三个类上:Rule、Map和MapAdapter。
Rule类继承自RuleFactory类。一个Rule的实例代表一个URL模式,一个WSGI应用可以处理很多不同的URL模式,这也就是说可以产生很多不同的Rule实例。这些Rule实例最终会作为参数传递给Map类,形成一个包含所有URL模式的对象,通过这个对象可以解析并匹配请求对应的视图函数。
关于Rule类有一些常用的方法:
rule实例化时至少接受一个参数,其他的都是默认参数。这个类实现了match,build等方法。主要的方法有get_url方法,这个方法重写了父类RuleFactory的方法,返回的是自身的生成器。这个方法与submain等其他的类的实现方法不同,在submain类中,这个类本身包含了rule类,故调用get_urls方法首先获得rule实例,再一次调用get_url得到一个生成器。
另外一个方法是bind方法,这个方法将rule实例绑定到map实例上,绑定后的rule能够使用map属性的方法。
通过Map类构造的实例可以存储所有的URL规则,这些规则是Rule类的实例。Map实例可以 通过后续的调用和给定的URL进行匹配。
关于Map类有一些常用的方法:
map类相当于一个存放Rule类的容器,实现的方法能对rule进行操作,也是url进入特定视图函数的中介。
MapAdapter主要是获取请求的url参数,将参数传递至相关视图函数中,进行处理。
Flask
Flask有两大核心:Werkzeug和Jinja2
Werkzeug实现路由,调试和web服务器网关接口,Werkzeug库的routing模块负责URL的解析,不同的URL对应不同的视图函数.
routing模块内部有:
Rule类: 用来构造不同的URL模式的对象,路由URL规则
Map类: 存储所有的URL规则和一些配置参数
BaseConverter的子类,负责匹配的规则
MapAdapter类: 负责协调Rule做具体的匹配工作
Jinja2实现模板.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "hello world"
if __name__ == "__main__":
app.run()
Flask模块介绍:
from flask import Flask
# __name__:会认为该文件所在的目录就是flask项目目录
# static_url_path:访问静态文件的前缀
# static_folder: 静态文件所在的目录文件夹名称
# template_folder:模板文件所在的目录文件夹名称
app = Flask(__name__,
static_url_path="/static",
static_folder ="static",
template_folder ="templates")
@app.route("/")
def index():
return "index"
if __name__ == "__main__":
app.run()
加载项目配置信息
from flask import Flask
# 自定义项目配置类
class Config(object):
DEBUG = True
app =Flask(__name__)
# 方式一:使用类的方式加载配置信息(重点)
app.config.from_object(Config)
# 方式二:在同级目录中建立一个配置文件(‘my.ini‘)
app.config.from_pyfile(‘my.ini‘)
# 方式三:使用环境变量方式加载项目配置信息
# 跟方式二一样,先写一哥配置文件,然后将文件的路径加入到环境变量中
# config的本质是一个字典
@app.route("/")
def hello():
# 两种方式获取字典的值,
# get方式获取不到则不会报错,默认为空
print(app.config.get("DEBUG",""))
# 找不到会报错
print(app.config["DEBUG"]")
return "hello world"
if __name__ == "__main__":
# 0.0.0.0表示本机所有ip均可访问, port代表端口号
app.run(host="0.0.0.0", port = 8888, debug=True)
转换器提取url路径的参数
from flask import Flask
app = Flask(__name__)
@app.route("/")
def demo1():
return "hello world"
# <user_id>转换器提取url路径的参数
# user_id的类型默认是字符串类型
# 127.0.0.1/user/字符串类型的数据
@app("/user/<user_id>")
def demo3(user_id):
return "user_id:%s" % user_id
# 限制输入的数据类型
# 127.0.0.1:5000/user_id/int数据类型
@app.route("/user_id/<int:user_id>")
def demo4(user_id):
return "user_id"% user_id
if __name__=="__main__"
app.run(debug=True)
请求方式:GET及POST
from flask import Flask
app = Flask(__name__)
# 不设置默认是get请求方式
@app.route("/")
def hello_world():
return "hello world"
# 设置post请求方式
@app.route("/post", methods=["POST"])
def demo():
return "post success"
if __name__ == "__main__":
print(app.url_map)
app.run(debug=True)
自定义转换器类
from flask import Flask
from werkzeug.routing import BaseConverter
app = Flask(__name__)
# 自定义转换器
class RegexConverter(BaseConverter):
# 重写regex属性,当你将正则表达式传入给它,BaseConverter类帮你处理
# url_map,re只是参数
def __init__(self, url_map, re):
# 初始化父类
super(RegexConverter, self).__init__(url_map)
self.regex = re
# 注册正则匹配类
# 往flask源码里面添加一个键值对
"""
往flask源码里面添加一个键值对
{
re:RegexConverter
}
"""
# 将re转换成RegexConverter类
app.url_map.converters["re"] = RegexConverter
# re("d{6}")-->RegexConverter(app.url_map, "d{6}")
@app.route("/user/<re("d{6}"):user_id>)
def demo1(user_id):
return "user %s" % user_id
if __name__ == "__main__":
app.run(debug=True)
获取请求参数:
data: 记录请求的数据
form: post请求中的表单数据
args: get请求中的参数
cookies: 记录请求中的cookie信息
headers: 记录请求中的报文头
method: 记录请求使用的http请求方法
url: 记录请求的URL地址
files:记录请求上传的文件
from flask import Flask, request
# 默认请求时get请求,127.0.0.1:5000/get?user_name=kangkang&age=18
@app.route("/get")
def demo1():
"""提取get请求号后面携带的参数"""
#request.method属性获取访问方式,后面的请求方式必须大写
if request.method == "GET":
user_name = request.args.get("user_name", "")
age = request.args.get("age")
return "%s %s" %(user_name, age)
else:
return "请求方式错误405!"
# post请求提取参数
# 需要指明请求方式为POST
@app.route("/post", methods = [‘POST‘])
def demo2():
if request.method == "POST":
user_name = request.form.get("user_name", "")
age = request.form.get("age", "")
return "%s %s"%(user_name, user_id)
else:
return "405请求方式错误"
# 文件上传
@app.route("/upload", methods=["POST"])
def demo3():
if request.method == "POST":
file = request.files.get("pic", "")
# 将图片保存到服务器本地
file.save("./1.png")
else:
return "405请求方式错误"
if __name__ == "__main__":
app.run(debug=True)
注意点:
GET:获取服务器的数据,问号里面携带的参数,告知服务器我要什么类型的数据
POST:往服务器新增数据,请求体里面携带参数,一般是需要存入的数据
构造响应数据:
import json
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/")
def demo1():
# json数据转换
dict = {
"name":"kangkang",
"age":24,
"info":{
"team":"laker"
}
}
# 序列化,将python对象转化成json字符串
json_str = json.dumps(dict)
# 反序列化:将json字符串转换成python对象
my_dict = json.loads(json_str)
# jsonify:能够将python对象转换成json对象
# 能够将响应体数据封装成响应对象并返回
# 指明了响应数据的格式:ContentType = "application/json"
my_json = jsonify(dict)
return my_json
if __name__ == "__main__":
app.run(debug=True)
重定向
from flask import Flask, redirect, url_for
# redirect:重定向,输入指定的路径会跳转到指定的地址
# url_for("要重定向的函数名称","参数值")
app = Flask(__name__)
@app.route("/index/<int:user_id>")
def hello(user_id):
return "hello %d" user_id
@app.route("/demo2")
def demo2():
# 重定向到百度
return redirect("www.baidu.com)
@app.route("/demo3")
def demo3():
# 重定向到指定的函数
# url_for:反向解析函数
# 传入的函数名称--->解析对应的url,根据app.app_url就能返回对应的url
return redirect(url_for(‘hello‘, user_id = 6666))
if __name__ == "__main__":
app.run(debug=True)
以上是关于Flask解析(二)路由(werkzeug.routing里 Map, Rule)的主要内容,如果未能解决你的问题,请参考以下文章