Flask Web开发学习笔记(2)

请求-响应循环

注:以下的请求意为Flask收到的请求,不是向别的服务器发送的请求,此时你已经是服务器了!响应同理。

一、上下文

首先我们要有一个概念,请求对象,它封装了客户端发送的HTTP请求

Python中默认为全局变量,为了防止使用混乱,引入上下文概念
可视为一种局部变量

Flask中,上下文分为 请求上下文应用上下文

1.请求上下文(request context)

  1. request : 请求对象,封装了HTTP请求
  2. session : 记录请求会话中信息的字典

如:

1
2
3
4
user = request.args.get('user') # HTTP请求

session['name'] = user.id   # 字典的用法
session.get('name')

request 和 session 在请求结束后就会被重置

注意:request 和 session 是两个变量名!不可变!下同理

2.应用上下文(application context)

  1. current_app : 当前激活的程序实例
  2. g : 请求时用作临时储存对象,每次请求后被清空

如:

1
2
current_app.name
g.name='abc'

二、请求调度

用 app.url_map 检查生成的映射
如查看 test.py 中的生成的映射(在py文件所在文件夹打开Python交互环境):

1
2
3
4
5
6
7
8
9
PS D:\桌面索引\编程\python\Flask Web开发\源码> python
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from test import app
>>> app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
     <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
     <Rule '/user/<id>' (HEAD, OPTIONS, GET) -> text_2>,
     <Rule '/user/<name>' (HEAD, OPTIONS, GET) -> text_1>])

三、请求钩子

时在处理请求之前或之后执行代码
Flask支持以下4种钩子:

  1. before_first_request:注册一个函数,在处理第一个请求之前运行。
  2. before_request:注册一个函数,在每次请求之前运行。
  3. after_request:注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行。
  4. teardown_request:注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行。

四、响应

1、Flask调用视图函数后,其返回值即为响应的内容

同时还需注意状态码,默认设为200,表示成功处理。若要单独定义,则需把数字代码作为第二个返回值
如:

1
2
3
@app.route('/')
def index():
    return '<h1>Bad Request</h1>', 400

2、Flask视图函数还可以返回Response对象

make_response()函数可接受参数和视图函数的返回值一样,返回一个Response对象
如:

1
2
3
4
5
6
from flask import make_response
@app.route('/')
def index():
    response = make_response('<h1>This document carries a cookie!</h1>')
    response.set_cookie('answer', '42')
    return response

3、重定向

该响应没有页面文档,只告诉浏览器一个新地址用以加载新页面。
常用302状态码表示
Flask提供了redirect()辅助函数,以生成这种响应:

1
2
3
4
from flask import redirect
@app.route('/')
def index():
    return redirect('http://www.baidu.com') # 重定向到百度

需要注意的是,这样写会报错:

1
2
3
4
5
6
7
@app.route('/')
def index():
    response = make_response(redirect('http://www.baidu.com'))
   
报错信息:
    TypeError: The view function did not return a valid response.
    The function either returned None or ended without a return statement

原因:漏掉了return response 。。。

同时网上还有人这样写:Flask通过make_response实现重定向

1
2
3
4
5
6
7
8
9
10
11
@app.route('/')
def index():
    headers = {
        'content-type':'text/plain',
        'location':'http://www.baidu.com'
    }
    # 使浏览器识别返回内容为字符串而不是html
    response = make_response("<html></html>",301)
    # 浏览器接收到301状态码之后,会在headers中寻找location以重定向
    response.headers = headers
    return response

4、错误处理

由abort函数生成
如:
若URL中动态参数id对应的用户不存在,返回状态码404

1
2
3
4
5
6
from flask import abort
@app.route('/user/<int:id>')
def text_2(id):
    if id != 123 :
        abort(404)
    return '<h1>Hello, %s</h1>' % id