一、装饰器路由的具体实现
1.Flask框架路由实现
Flask有两大核心:Werkzeug和Jinja2
- Werkzeug实现路由、调试和Web服务器网关接口
- Jinja2实现了模板。
Werkzeug是一个遵循WSGI协议的python函数库
- 其内部实现了很多Web框架底层的东西,比如request和response对象;
- 与WSGI规范的兼容;支持Unicode;
- 支持基本的会话管理和签名Cookie;
- 集成URL请求路由等。
2. Flask框架中实现route的方法:
Werkzeug库的 routing 模块负责实现 URL 解析。不同的 URL 对应不同的视图函数,routing模块会对请求信息的URL进行解析,匹配到URL对应的视图函数,执行该函数以此生成一个响应信息。
routing模块内部有:
- Rule类
-
- 用来构造不同的URL模式的对象,路由URL规则
- Map类
-
- 存储所有的URL规则和一些配置参数
- BaseConverter的子类
-
- 负责定义匹配规则
- MapAdapter类
-
- 负责协调Rule做具体的匹配的工作
二、上下文:
1.上下文:
相当于一个容器,保存Flask程序运行过程中的一些信息。
Flask中有两种上下文:
- 请求上下文;
- 应用上下文;
2.请求上下文(request Context):
在 flask 中,可以直接在视图函数中使用 request 这个对象进行获取相关数据,而 request 就是请求上下文的对象,保存了当前本次请求的相关数据,请求上下文对象有:request、session
- request
– 封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get(‘user’),获取的是get请求的参数。 - session
– 用来记录请求会话中的信息,针对的是用户信息。举例:session[‘name’] = user.id,可以记录用户信息。还可以通过session.get(‘name’)获取用户信息。
2.1.request获取请求参数:
request 就是flask中代表当前请求的 request 对象,其中一个请求上下文变量(理解成全局变量,在视图函数中直接使用可以取到当前本次请求)。
常用的属性如下:
属性 | 说明 | 类型 |
data | 记录请求的数据,并转换为字符串 | * |
form | 记录请求中的表单数据 | MultiDict |
args | 记录请求中的查询参数 | MultiDict |
cookies | 记录请求中的cookie信息 | Dict |
headers | 记录请求中的报文头 | EnvironHeaders |
method | 记录请求使用的HTTP方法 | GET/POST |
url | 记录请求的URL地址 | string |
files | 记录请求上传的文件 | * |
代码演示:
request常用的属性:args、from、method、files、headers、url
args属性的代码实例:
# GET请求:arg查询字符串,获取请求url地址中的查询字符串参数
# 127.0.0.1:5000/args_demo?name=hahah&age=18 使用?号查询,条件使用&分隔
@app.route("/args_demo", methods = ["POST", "GET"])
def demo_args():
if request.method == "GET":
name = request.args.get('name')
age = request.args.get('age')
print(name, age)
return "GET response..."
else:
# 如果是post请求,接收的是表单数据
itcast = request.form.get('itcast')
age = request.form.get('age')
print(itcast, age)
return 'POST response...'
files属性的代码实例:
# files属性:
@app.route("/images", methods=['GET', 'POST'])
def get_image():
# 获取图片使用post方法,通过files属性获取
image = request.files.get("image")
# 保存图片
image.save("./demo01.jpg")
return 'save image success...'
url属性的代码实例
# url属性
# 测试用例:127.0.0.1:5000/
@app.route("/", methods=["GET", "POST"])
def param_url():
print("请求方法:" + str(request.method))
print("请求头:" + str(request.headers))
print("请求url:" + str(request.url))
return "请求url..."
3.应用上下文:
它的字面意思是 应用上下文,但它不是一直存在的,它只是request context 中的一个对 app 的代理(人),所谓local proxy。它的作用主要是帮助 request 获取当前的应用,它是伴 request 而生,随 request 而灭的。
应用上下文对象有:
- current_app;
- g变量;
3.1 current_app
应用程序上下文,用于存储应用程序中的变量,可以通过current_app.name打印当前app的名称,也可以在current_app中存储一些变量,例如:
- 应用的启动脚本是哪个文件,启动时指定了哪些参数;
- 加载了哪些配置文件,导入了哪些配置;
- 连了哪个数据库;
- 有哪些public的工具类、常量;
- 项目中用来记录项目日志;
- 应用跑再哪个机器上,IP多少,内存多大;
current_app.name
current_app.test_value=‘value’
3.2 g变量:
g 作为 flask 程序全局的一个临时变量,充当者中间媒介的作用,我们可以通过它传递一些数据,g 保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别。
g.name=‘abc’
注意:不同的请求,会有不同的全局变量
3.3 两者区别:
- 请求上下文:保存了客户端和服务器交互的数据
- 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等
上下文中的对象只能在指定上下文中使用,超出范围不能使用 请求上下文和应用上下文原理实现:
参考文章:https://segmentfault.com/a/1190000004223296
三、Flask-Script扩展:
通过使用Flask-Script扩展,我们可以在Flask服务器启动的时候,通过命令行的方式传入参数。而不仅仅通过app.run()方法中传参,比如我们可以通过:
python hello.py runserver -host ip地址
以上代码告诉服务器在哪个网络接口监听来自客户端的连接。默认情况下,服务器只监听来自服务器所在的计算机发起的连接,即localhost连接。
Flask-Scritp扩展包的作用:
- 在终端中手动输入host和port等;
- 进行数据库的迁移;
- 自定义命令;
3.2 使用语法:
# !/usr/bin python3
# coding=utf8
from flask import Flask
from flask_script import Manager
app = Flask(__name__)
app.config['DEBUG'] = True
manage = Manager(app)
@app.route("/")
def index():
return "hello world"
if __name__ == '__main__':
# app.run()
# 启动服务器不用打开代码,可使用终端手动的启动服务,动态的传入host和port
manage.run()
启动方法: