IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 【Flask学习】1.2Flask的工作方式 -> 正文阅读

[Python知识库]【Flask学习】1.2Flask的工作方式


上一节我们开发了1个简单的Flask程序,并且知道它的最基本运行逻辑:创建1个程序实例,然后定义1个或多个路由,最后启动web服务器去轮询处理收到的请求。
或许此时你对“ 程序实例收到请求并给予响应的过程”有些疑惑,我也是,下来我们一起探索。

程序和请求上下文

Flask程序实例收到从客户端发来的请求时,要让视图函数能访问一些对象,这样才能更好处理请求。
请求对象,就是1个很好的例子,它封装了客户端发送的HTTP请求。

要让视图函数能够访问请求对象,Flask使用上下文临时把某些对象变成全局可访问(仅单个线程)。有了上下文,就可以这样访问对象:

from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def index():
	"""访问请求对象的请求头"""
	user_agent = request.headers.get('User-Agent')
	return '<h1>Your browser is %s.</h1>' % user_agent

if __name__ == '__main__':
	app.run(debug=True)

在Flask中有两种上下文:程序上下文和请求上下文,一些说明如下:

变量名上下文说明
current_app程序上下文当前激活程序的程序实例
g程序上下文处理请求时用作临时存储的对象,每次请求都会重设这个变量
request请求上下文请求对象,封装了客户端发出的HTTP请求的内容
session请求上下文用户会话,用于存储请求之间需要“记住”的值的字典

Flask在分发请求之前激活(或推送)程序和请求上下文,那么就可以使用上面几个变量了,且请求处理完成后会将它删除。
如果在使用全局变量前没有激活上下文,就会导致错误。下面在python shell会话演示程序上下文的使用方法:

(website) D:\Flask>python
......
>>> from hello import app
>>> from flask import current_app
>>> current_app.name		# 没激活程序上下文之前就使用全局变量current_app,会导致错误
Traceback (most recent call last):
...
RuntimeError: working outside of application context
>>> app_ctx = app.app_context()		# 获得1个程序上下文
>>> app_ctx.push()			# 推送程序上下文
>>> current_app.name
'hello'
>>> app_ctx.pop()		# 删除程序上下文

请求调度

程序收到客户端发来的请求时,要找到能处理该请求的视图函数。要完成这个动作,Flask会在程序的URL映射中查找请求的URL。

URL映射,是URL和视图函数的对应关系。
在Flask中,使用 app.route 修饰器或者非修饰器形式的 app.add_url_rule() 生成映射。

你想看看Flask程序中的URL映射是什么样子?我们可以在python shell会话中用app.url_map查看。

(venv) $ python
>>> from hello import app
>>> app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
 <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
 <Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])

/ 和 /user路由在程序中使用 app.route 修饰器定义。/static路由是Flask 添加的特殊路由,用于访问静态文件。
Flask为每个路由都指定了请求方法,这样在收到相同的URL、不同的请求方法,(可能)会使用不同的视图函数处理。在目前的例子中@app.route()都未指定methods值,但是有HEAD/OPTIONS/GET方法,可以看出这些是默认的,Flask提供了很大的便利!

请求钩子

有时我们需要在处理请求之前或者之后执行代码,比如创建数据库连接,这些会很有用。为了避免在每个视图函数使用重复的代码,我们可以用Flask提供的注册通用函数的功能,注册的函数即在处理请求之前或之后调用。
请求钩子使用修饰器实现,Flask支持下面4种钩子:

函数说明
before_first_request在处理第一个请求之前运行
first_request在每次请求之前运行
after_request如果没有未处理的异常抛出,在每次请求之后运行
teardown_request即使有未处理的异常抛出,也在每次请求之后运行

在请求钩子函数和视图函数之间共享数据,一般使用上下文全局变量g。比如,before_request获取已登录用户,并将其保存到g.user,视图函数就可方便地使用已登录用户的数据。
请求钩子使用例子如下:

from flask import Flask, g
from datetime import datetime

app = Flask(__name__)

@app.before_request
def run_before_request():
	"""访问请求对象的请求头"""
	cur_time = time.strftime('%Y.%m.%d %H:%M:%S', time.localtime())
    log_msg = "Request arrivered at %s, please note." % cur_time
    g.begin_time = cur_time
    print(log_msg)

@app.route('/')
def index():
	return '<h1>Hello, Every.</h1><h2>Now is at %s.</h2>' % g.get('begin_time', '2000.10.1 9:00:00')

if __name__ == '__main__':
	app.run(debug=True)

请求http://127.0.0.1:5000/后,服务器日志有run_before_request打印的内容,且请求到达的时间g.begin_time也共享了视图函数使用。

响应

大多数情况,响应是1个简单的字符串,像前面的例子。但HTTP协议需要的不仅是响应的字符串,还有1个重要的组成–状态码,Flask默认设为200,代表请求已被成功处理。
如果需要返回不同的状态码,则把状态码数字作为响应的第2个参数。例如:

@app.route('/error')
def bad_request():
	return '<h1>Bad Request.</h1>', 400

返回的函数还可接受第3个参数,这是1个字典结构的响应头部(Header)。如果不想返回由 1 个、2 个或 3 个值组成的元组,Flask 视图函数还可以返回 Response 对象。make_response() 函数可接受 1 个、2 个或 3 个参数(和视图函数的返回值一样),并返回一个 Response 对象。有时我们需要在视图函数中进行这种转换,然后在响应对象上调用各种方法,进一步设置响应。

from flask import make_response

@app.route('/')
def index():
 response = make_response('<h1>Tomorrow will come!</h1>')
 response.set_cookie('gift', 'flower')
 return response

有1种名为重定向的特殊响应类型,只告诉浏览器一个新地址用来加载新页面。重定向经常使用302状态码表示,指向的地址由location首部提供。
在Flask,提供了redirect()函数生成这种响应:

from flask import redirect

@app.route('/redirect')
def to_redirect():
 return redirect('http://www.funny.com/new')
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:52:04  更:2022-10-31 11:52:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 3:23:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计