Flask Web开发——(一)应用的基本结构

本文介绍了如何使用Flask创建基本应用,包括初始化应用实例,配置路由与视图函数,动态路由,以及利用PyCharm开发服务器。还讨论了调试模式、命令行选项和请求响应流程,展示了如何处理请求和设置响应,包括cookies和状态码。
摘要由CSDN通过智能技术生成

一、初始化
所有Flask应用都必须创建一个应用实例。Web服务器使用WSGI协议,把自客户端的请求转交给这个对象处理。应用实例是Flask类的对象:

from flask import Flask
app = Flask(__name__)

Flask应用__name__参数确定应用的位置,进而找到应用中其他文件的位置,如图像和模板。

二、路由和视图函数
客户端把请求发送给Web服务器,Web服务器再把请求发送给Flask应用实例。应用实例需要知道对每个URL的请求要运行哪些代码,所有保存了一个URL到Python函数的映射关系。
处理URL和函数之间关系的程序称为路由。

使用应用实例提供的 app.route 装饰器声明路由:

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

前例把index()函数注册为应用根地址的处理程序。

app.add_url_rule()方法,3个参数:URL、端点名、视图函数:

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

index()这样处理入站请求的函数称为视图函数。例如,若将应用部署在域名为www.example.com的服务器上,在浏览器中访问http://www.example.com后,会触发服务器执行index()函数。
函数的返回值称为响应,是客户端接收到的内容。

很多地址中都包含可变部分。如Facebook资料页面地址是http://www.facebook.com/ , username是地址的一部分. Flask支持这种形式的URL, 在app.route装饰器中使用特殊的句法即可:

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

路由URL在尖括号里的内容是动态部分. 任何匹配静态部分的URL都会映射到这个路由上.
路由中的动态部分默认使用字符串, 也可是其他类型, 如: /user/int:id只匹配动态片段id为整数的URL, 如/user/123.

三、一个完整的应用

from flask import Flask
app = Flask(__name__) #应用实例

@app.route('/')       #路由
def index():          #视图函数
    return '<h1>Hello World!</h1>'

四、利用pycharm启动Web开发服务器
启动代码:

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

完整代码:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'
 
if __name__ == '__main__':
    app.run(debug=True)          

成功后可以通过访问http://127.0.0.1:5000/ 来查看效果。

五、动态路由
例:hello.py

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)

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

应用会显示一个使用name动态参数生成的消息:
在这里插入图片描述

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

启用重载器后,Flask会监视项目中的所有源码文件,发现变动时自动重启服务器。在开发过程中运行启动重载器的服务器非常方便,因为每次修改并保存源码文件后,服务器都会自动重启,让改动生效。

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

在pycharm上启动调用模式:
1、编辑结构Edit Configurations
在这里插入图片描述

2、修改环境变量Environment variables,添加FLASK_DEDBUG=1
3、以编程的方式启动调试模式,添加app.run(debug=True):

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

不要在生产服务器中启用调试模式。客户端通过调试器能请求执行远程代码,因此可能导致生产服务器遭到攻击。作为一种简单的保护措施,启动调试模式时可以要求输入PIN码,执行flask
run命令会打印在控制台中。

七、命令行选项
在pycharm中使用Help()(查看帮助文档)。
选择目标代码——视图——快速定义
View - Quick Definition
选择目标代码——试图——快速文档

八、请求—响应循环
(一)、应用和请求上下文
Flask从客户端收到请求时,需让试图函数能访问一些对象,才能处理请求。请求对象是一个很好的例子,它封装了客户端发送的HTTP请求。

让视图函数能够访问请求对象最直接的方式,是将其作为参数传入视图函数。
缺点:导致应用中每个视图函数都多处一个参数。

除了访问请求对象,如果视图函数在处理请求时还要访问其他对象,就更乱了。

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

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

上下文就像一个额外的辅助性容器一样,request存储用户代理,同时成为一个全局变量(但实际并不是)。Flask使用上下文让特定的变量在一个线程中全局可访问,并且不会干扰其他线程。

线程是可单独管理的最小指令集。进程经常使用多个活动线程,有时还会共享内存或文件句柄等资源。多线程Web服务器会创建一个线程池,再从线程池中选择一个线程处理接收到的请求。

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

Flask在分派请求之前激活(或推送)应用和请求上下文,请求处理完成后再将其删除。应用上下文被推送后,就可以在当前线程中使用current_app和g变量。同理request和session变量。使用前一定要激活,否则会报错。

应用上下文的使用方法:

>>>from hello import app
>>>from flask import current_app
>>>app_ctx() = app.app_context()
>>>app_ctx.push()
>>>current_app.name
'hello'
>>>app_ctx.pop()

注意:获取应用上下文的方法是在应用实例上调用app.app_context()。调用前要激活应用。

(二)、请求分派
URL映射是URL和视图函数之间的对应关系
查看hello.py中生成的映射:
在pycharm中选择Terminal(pycharm 2016.3之后的Terminal已不需要特意指定路径激活,直接调用即可)。

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

/和/user/是用app.route定义,/static/ 路由是 Flask 添加的特殊路由,用于访问静态文件。

URL映射中的 HEAD、Options、GET 是请求方法,由路由进行处理。Flask为每个路由都指定了请求方法,这样不同的请求方法发送到相同的URL 上时,会使用不同的视图函数进 行处理。HEAD 和OPTIONS 方法由 Flask 自动处理。

ps:我一开始在请求调度时,from hello import app一直出现model not found的问题,把根目录文件夹mark
as source
root也不好使。结果…在运行hello.py的同时选择Terminal,就可以import了,我尼玛…叫自己蠢死了。

(三)、请求对象
Flask通过上下文变量request对外开放请求对象,它包含客户端发送的HTTP请求的全部信息。
Flask请求对象中最常用的属性和方法表:
属性或方法 说明
form 字典,存储请求提交的所有表单字段
args 字典,存储通过URL查询字符串传递的所有参数
values 字典,form和args的合集
cookies 字典,存储所有的cookie
headers 字典,存储请求的所有HTTP首部
files 字典,存储请求上传的所有文件
get_data() 返回请求主体缓冲的数据
get_json() 返回一个python字典,包含解析请求主体后得到的JSON
blueprint 处理请求的Flask蓝本的名称

endpoint 处理请求的Flask端点的名称,Flask把视图函数的名称用作路由断点的名称
method HTTP请求方法
scheme URL方案(http或https)
is_secure() 通过安全的连接(HTTPS)发送请求时返回True
host 请求定义的主机名,若客户端定义了端口号,还包括端口号
path URL的路径部分
query_string URL的查询字符串部分,返回原始二进制值
full_path URL的路径和查询字符串部分
url 客户端请求的完整URL
base_url url,但无查询字符串部分

remote_addr 客户端的IP地址
environ 请求的原始WSGI环境字典

(四)、请求钩子
在请求开始时,可能需要创建数据库连接或者验证发起请求的用户身份。为避免在每个视图函数中都重复编写代码,Flask提供了注册通用函数功能,注册的函数可在请求被分派视图函数之前或之后调用。

请求钩子通过装饰器实现。Flask支持以下4种钩子:
before_request
注册一个函数,在每次请求之前运行。
before_first_request
注册一个函数,只在处理第一个请求之前运行。
after_request
注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行。
teardown_request
注册一个函数,即使有未处理的异常抛出,在每次请求之后运行。

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

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

HTTP响应中一个很重要的部分是状态码,Flask默认设为200,表面请求已被成功处理。

如果视图函数返回的响应需要使用不同的状态码,可把数字代码添加为第二个返回值,添加到响应文本之后。
返回400状态码,表示请求无效:

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

第三个参数:由HTTP响应首部组成的字典。

Flask视图函数还可以返回一个响应对象。make_response()可以接受1个、2个或3个参数(和视图函数的返回值一样,看下例),然后返回一个等效的响应对象。有时我们需要在视图函数中生成响应对象,然后在响应对象上调用各个方法,进一步设置响应。(沃日,没看明白)
下例创建一个响应对象,然后设置cookie:

from flask import make_response

@app.route('/')
def index():
    response = make_response('<h1>This documnet carries a cookie!</h1>')
    response.set_cookie('answer', '42')
    return response        

响应对象最常使用的属性和方法表:
属性或方法 说明
status_code HTTP数字状态吗
headers 类似字典的对象,包含随机响应发送的所有首部
set_cookie() 为响应添加一个cookie
delete_cookie() 删除一个cookie
content_length 响应主体的长度
content_type 响应主体的媒体类型
set_data() 使用字符串或字节值设定响应
get_data() 获取响应主体

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

重定向的状态码通常是302。

Flask提供了redirect()辅助函数,用于生成这种响应:

from flask import redirect

@app.route('/')
def index():
    return redirect('http://ww.example.com')

有一种特殊的响应由abort()函数生成,用于处理错误。如下例,如果URL中动态参数id对应的用户不存在,就返回状态码404:

from flask import abort

@app.route('/user/<id>')
def get_user(id):
    user = load_user(id)
    if not user:
        abort(404)
    return '<h1>Hello, {}</h1>'.format(user.name)        

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值