Web开发-Flask从零开始的学习(一)


目录
  • 1 基本介绍
  • 2 应用的基本结构
    • 路由和视图函数
    • 简单应用和Web服务启动
    • 动态路由
    • 调试模式
    • 命令行选项
    • 应用和请求上下文
    • 请求分派
    • 请求对象
    • 请求钩子
    • 响应
  • flask拓展

1 基本介绍

Flask 自开发伊始就被设计为可扩展的框架,它具有一个包含基本服务的强健核心,其他功能则可通过扩展实现。

Flask 有 3 个主要依赖:路由、调试和 Web 服务器网关接口

2 应用的基本结构

所有 Flask 应用都必须创建一个应用实例。

from flask import Flask
app = Flask(__name__)

路由和视图函数

客服端发送请求到服务器,服务器把请求发送给flask应用实例。应用实例保存url到python函数的映射关系,不同函数处理不同url请求。而处理这种映射关系的关系称之为路由。

  • 使用装饰器注册路由函数:index函数注册为根目录的处理程序
@app.route('/')
def index():
    return '

Hello world!

'
  • 传统方式:app.add_url_rule
def index():
    return '

Hello world!

' app.add_url_rule('/','index',index) # URL 端点名 视图函数

视图函数的返回值称为响应,为客户端接收到的内容

  • URL中的可变内容
@app.route('/user/') # <>内动态部分
def index():
    return '

Hello {}

'.format(name)

路由 URL 中放在尖括号里的内容就是动态部分,任何能匹配静态部分的 URL 都会映射到这个路由上。调用视图函数时,Flask 会将动态部分作为参数传入函数

路由中的动态部分默认使用字符串。

Flask 支持在路由中使用 string、int、float 和 path 类型。path 类型是一种特殊的字符串,与 string 类型不同的是,它可以包含正斜线。

/user/ 只会匹配动态部分id为整数的URL

简单应用和Web服务启动

from flask import  Flask
app = Flask(__name__)

@app.route('/')
def index():
    return '

Hello world!

'

Flask 应用自带 Web 开发服务器,通过 flask run 命令启动。

这个命令在 FLASK_APP 环境变量指定的 Python 脚本中寻找应用实例。

Windows下:

  • 确保激活所在Flask所在环境

  • 执行命令

set FLASK_APP = hello.py # 自己的实例py文件
flask run

或者可以在py脚本加上

app.run()

目前只是开发状态

动态路由

在前面的基础上利用动态部分来实现访问动态URL

调试模式

Flask 应用可以在调试模式中运行。在这个模式下,开发服务器默认会加载两个便利的工具:重载器调试器

  • 重载器:启用重载器后,Flask 会监视项目中的所有源码文件,发现变动时自动重启服务器。每次修改并保存源码文件后,服务器都会自动重启,让改动生效。

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

调试模式默认关闭,在flask run之前需要设置FLASK_DEBUG=1环境变量。

set FLASK_DEBUG=1 # Windows环境下set设置环境变量

命令行选项

这里只是告诉大家有一些选项参数可以选择或帮助我们后续的使用:

flask命令支持一些参数选项 flask shell


flask run --host参数告诉Web服务器在哪个网络接口监听客户端的连接。默认监听localhost的连接,即只接受运行Web服务器的计算机的连接请求。

flask run --host 0.0.0.0

接受同一网络中所有计算机的连接请求

请求-响应循环 (简单介绍HTTP)

应用和请求上下文

Flask从客户端收到请求,视图函数通过访问请求对象来获取信息处理请求。

Flask 使用上下文临时把某些对象变为全局可访问。

from flask import request
@app.route('/')
def index():
	user_agent = request.headers.get('User-Agent')
	return '

Your browser is {}

'.format(user_agent)

这里例子把request当作全局变量使用

多线程 Web 服务器会创建一个线程池,再从线程池中选择一个线程处理接收到的请求。


上下文:应用上下文和请求上下文。举例:

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

Flask 在分派请求之前激活(或推送)应用和请求上下文,请求处理完成后再将其删除。

应用上下文被推送后,就可以在当前线程中使用 current_app 和 g 变量。同理,请求上下文被推送后,就可以使用 request 和 session 变量。如果使用这些变量时没有激活应用上下文或请求上下文,就会导致错误。

请求分派

应用收到客户端发来的请求时,要找到处理该请求视图函数。为了完成这个任务,Flask会在应用的 URL 映射中查找请求的 URL。URL 映射是 URL 和视图函数之间的对应关系。

Flask构建映射:

  • app.route装饰器
  • app.add_url_rule方法

查看Flask应用中的映射:

  • app.url_map
# python shell下
>>> from hello import flask
>>> app.url_map

URL 映射中的 (HEAD, OPTIONS, GET) 是请求方法,由路由进行处理。HTTP 规范中规定,每个请求都有对应的处理方法,这通常表示客户端想让服务器执行什么样的操作。Flask为每个路由都指定了请求方法,这样即使不同的请求方法发送到相同的 URL 上时,也会使用不同的视图函数处理。HEAD 和 OPTIONS 方法由 Flask 自动处理

请求对象

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

具体常用的属性和方法暂时略

page36

请求钩子

有时在处理请求之前或之后执行代码会很有用。

比如:在请求开始时,我们可能需要创建数据库连接或者验证发起请求的用户身份。

为了避免在每个视图函数中都重复编写代码,Flask 提供了注册通用函数的功能,注册的函数可在请求被分派到视图函数之前或之后调用。

请求钩子通过装饰器实现,目前flask支持如下4种:

  • before_request:注册一个函数,每次请求前运行
  • before_firest_request:注册一个函数,只在处理第一个请求前运行
  • after_request:注册一个函数,如果没有未处理的异常抛出,每次请求之后运行。
  • teardown_request:注册一个函数,即使有未处理的异常抛出,每次请求之后运行。

在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量 g。例如,before_request 处理程序可以从数据库中加载已登录用户,并将其保存到 g.user 中。随后调用视图函数时,便可以通过g.user 获取用户

响应

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

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

视图函数的返回:

  • 如果视图函数返回的响应需要使用不同的状态码,可以把数字代码当作第二个返回值
@app.route('/')
def index():
    return '

hello world

',400
  • 视图函数的返回还可以接受第三个参数,这是一个由 HTTP 响应首部组成的字典
  • 视图函数如果不想返回由 1 个、2 个或 3 个值组成的元组,Flask 视图函数还可以返回一个响应对象
from flask import make_response
@app.route('/')
def index():	
    response = make_response('

This document carries a cookie!

') response.set_cookie('answer', '42') return response

make_response() 函数可接受 1 个、2 个或 3 个参数,然后返回一个等效的响应对象。有时我们需要在视图函数中生成响应对象,然后在响应对象上调用各个方法,进一步设置响应

page37


响应有个特殊的类型,称为重定向。这种响应没有页面文档,只会告诉浏览器一个新URL,用以加载新页面,重定向经常在 Web 表单中使用。

重定向的状态码通常是 302,在 Location 首部中提供目标 URL。

  1. 重定向响应可以使用 3个值形式的返回值生成,也可在响应对象中设定。

  2. 由于重定向响应使用频繁,提供了redirect() 辅助函数。

from flask import redirect
@app.route('/')
def index():
    return redirect('http://www.example.com')

还有一种特殊的响应由 abort() 函数生成,用于处理错误。

from flask import abort
@app.route('/user/')
def get_user(id):
	user = load_user(id)
	if not user:
	abort(404)
	return '

Hello, {}

'.format(user.name)

abort() 不会把控制权交还给调用它的函数,而是抛出异常

flask拓展

Flask 的设计考虑了可扩展性,故而没有提供一些重要的功能,例如数据库和用户身份验证,所以开发者可以自由选择最适合应用的包,或者按需求自行开发。
所有学习内容基于《Flask Web开发:基于Python的Web应用开发实战》