《Flask Web开发》-第二章-应用的基本结构

2.1 初始化

所有Flask应用都必须创建一个应用实例
Web服务器使用一种名为Web服务器网关接口(WSGI, Web server gateway interface,读作“wiz-ghee”)的协议,把接收自客户端的所有请求都转交给这个对象处理。

应用实例是Flask类的对象,由下面代码创建

from flask import Flask
app = Flask(__name__)  #Flask为一个类  

Flask类的构造函数只有一个必须指定的参数,即应用主模块或者包的名称。大多数情况下,Python的__name__变量就是所需的值。Flask使用__name__来确定应用的位置,进而找到应用中其他文件的位置,如图像和模板


2.2 路由和视图函数

客户端(例如Web浏览器)把请求发送给Web服务器,Web服务器再把请求发送给Flask应用实例。应用实例需要知道对每个url的请求运行那些代码,所以保存了url到Python函数的映射关系。处理URL和函数之间关系的程序被称为路由

@app.route('/')  # 使用app.route装饰器来定义路由
 def index():   # 把index()函数注册为应用根地址的处理程序
     return '<h1>Hello World!</h1>'

def index():  # 将index函数注册为应用根地址的处理程序
    return'<h1>Hello World!</h1>'
app.add_url_rule('/','index',index)   # app.add_url_rule()接收3个参数:URL,端点名,视图函数

index()这样处理入站请求的函数称为视图函数。如果应用部署在域名为www.bilibili.com的 服务器上,在浏览器中访问http://www.bilibili.com 后,会触发服务器执行index()函数。这个函数的返回值称为响应,是客户端收到的内容。如果客户端是Web浏览器,响应就是显示给用户查看的文档。视图函数返回的响应可以是包含HTML的简单字符串。

@app.route('/user/<name>')   # 定义的路由有一部分是可变的
def user(name):
return '<h1>Hello,{}!</h1>'.format(name)  # 路由URL在{}的内容就是动态部分

调用视图函数时,Flask会将动态部分作为参数传入参数。name参数用于生成个性化的欢迎信息。
路由中的动态部分默认是字符串,也可为其他。如路由/user/int:id只会匹配动态片段id为整数的URL,如/user/123。Flask支持路由中使用string, int, float和path类型(path为一种特殊的字符串,特殊之处在于可以包含正斜线)

装饰器是Python语言的标准特性。惯常用法是把函数注册为时间处理程序,在特定事件发生时使用


2.4 Web开发服务器

Flask应用自带Web开发服务器,通过flask run命令启动。这个命令在FLASK_APP环境变量指定的Python脚本中寻找应用实例

Flask提供的Web服务器只适用于开发和测试。

Flask Web开发服务器也可以通过编程的方式启动:调用app.run()方法


2.5 动态路由

添加一个动态路由。在浏览器中访问中国动态URL,会看到一条个性化的信息

hello.py: 包含动态路由的Flask应用

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

@app.route('/user/<name>')
def user(name):
    return '<h1>Hello,{}!</h1>'.format(name)

2.6 调试模式

Flask应用可以在调试模式中运行,在此模式下,开发服务器默认会加载两个工具:重载器和调试器。
启用重载器后,Flask会监视项目中的所有源码文件,发现变动时自动重启服务器。在开发过程中运行启动重载器的服务器特别方便,因为每次修改并且保存源码文件以后,服务器都会自动重启,让改动生效

调试器是一个基于Web的工具,当应用抛出未处理的异常时,它会出现在浏览器中。此时,Web浏览器变成一个交互式栈跟踪,可以在里面审查源码,在调用栈的任何位置计算表达式

调试模式默认禁用,在执行flask run之前设定FLASK_DEBUG=1可以启用调试器


2.7 命令行选项

flask --help或者flask可以查看那些选项可以使用
flask shell 在应用上下文打开一个Python shell会话,在会话中可以运行维护任务或者测试,也可以调试问题
flask run 在Web开发服务器中运行应用
flask run --host 告诉服务器在那个网络接口上监听客户端发来的连接
Flask的Web服务器在监听localhost上的连接,因此服务器只接受运行服务器的计算机发送的连接
flask run --host 0.0.0.0 让Web服务器监听公共网络接口上的连接


2.8 请求-响应循环

2.8.1 请求和应用上下文

flask从客户端收到请求时,要让视图函数能访问一些对象,才能处理请求。请求对象封装了客户端发送的http请求

为了避免大量参数把视图函数搞得一团糟,Flask使用上下文临时把某些对象变为全局可访问。有上下文可以这样编写视图函数:

from flask import Flask
		
@app.route('/')
def index():
    user_agent = request.headers.get('User-Agent')
	return '<p>Your browser is {}</p>'.format(user_agent)

此视图函数中,request为全局变量(事实上,不可能是全局变量,在多线程服务器中,多个线程同时处理不同客户端发送的不同请求时,每个线程看到的request对象必然不同。Flask使用上下文让特定的变量在一个线程中全局可访问,与此同时却不会干扰其他线程)
在这里插入图片描述
flask在分配请求之前激活(或推送)应用和请求上下文,请求处理完成后再将其删除。应用上下文被推送后,就可以在当前线程中使用current_app和g变量。

请求上下文被推送后,就可以使用request和session变量。如果变量未激活应用上下文或请求上下文,就会错误。
运行

from hello import app
from flask import current_app
current_app.name    # 未激活应用上下文调用会失败

输出

Traceback (most recent call last):
...


运行

 app_ctx = app.app_context()  # 获取上下文,推送完上下文就可以调用
    app_ctx.push()
    current_app.name

输出

'hello'


运行

 app_ctx.pop()

2.8.2 请求分配

应用收到客户端发来的请求时,要找到处理该请求的视图函数,flask会在应用的url映射中查找请求的url。url映射是url与视图函数之间的对应关系。flask应用app.route装饰器或者app.add_url_rule()方法构建映射

from hello import app 
app.url_map # 查看flask应用中的url映射

Map([<Rule '/' (OPTIONS, GET, HEAD) -> index>,
 <Rule '/static/<filename>' (OPTIONS, GET, HEAD) -> static>,
 <Rule '/user/<name>' (OPTIONS, GET, HEAD) -> user>])	

/和/user/路由在应用中使用app.route定义
/static/是flask添加的特殊路由,用于访问静态文件

url映射中的(HEAD,OPTIONS,GET)是请求方法,由路由进行处理
flask为每个路由都指定了请求方法,所以即使不同的请求方法发送到相同的url上时,也会使用不同的视图函数处理。HEAD和OPTIONS由flask处理。
可以这样说,在此应用中,url映射中的3个路由都使用GET方法(表示客户端想请求一个如网页的消息)


2.8.3 请求对象

flask通过上下文变量request对外开放请求对象,此对象包含客户端发送的HTTP请求的全部信息。

flask常用的属性与方法
在这里插入图片描述
在这里插入图片描述
2.8.4 请求钩子

为了避免在每个视图函数中都重复编写代码,Flask提供了注册通用函数功能,注册的函数可以在请求被分配到视图函数之前或之后调用。
请求钩子通过装饰器实现。

flask支持以下四种钩子:

  • before_request
    注册一个函数,在每次请求之前运行
  • before_first_request
    注册一个函数,只在处理第一个请求之前运行。可以添加服务器初始化任务
  • after_request
    注册函数,若未出现未处理的异常,则在每次请求之后运行
  • teardown_request
    注册函数,即使有未处理的异常抛出,也在每次请求之后运行

在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量g


2.8.5 响应

flask调用视图函数后,会将其返回值作为响应的内容。多数情况下,响应就是一个简单的字符串,作为html页面回送客户端。

但是HTTP协议需要的不仅仅是请求响应的字符串,HTTP中很重要的是状态码,flask默认为200,表明请求已被成功处理

如果视图函数返回的响应需要使用不同的状态码,可以把数字代码作为第二个返回值,添加到响应文本之后。

make_response()可以接受1、2、或3个参数(和视图函数的返回值一样),然后返回一个等效的响应对象。有时需要在视图函数中生成响应对象,然后在响应对象上调用各个方法,进一步设置响应
在这里插入图片描述
重定向响应没有页面文档,只会告诉浏览器一个新的url,用以加载新页面。

重定向的状态码通常是302,在location首部中提供目标url,重定向响应可以使用3个值形式的返回值生成,也可以在响应对象中设定。

flask提供的redirect()函数可以生成重定向响应:

from flask import redirect

@app.route('/')
def index():
    return redirect('http://www.bilibili.com')

abort()函数用于处理错误

from flask import abort

@app.route('/user/<id>')
def get_user(id):
    user = load_user(id)
    if not user:
        abort(404)  # 若url中动态参数id对应的用户不存在,则返回状态码404,abort()不会把控制权交给调用函数,而是抛出异常
    return '<h1>Hello,{}</h1>'.format(user.name)

猜你喜欢

转载自blog.csdn.net/qq_40061206/article/details/91443830