Flask建站

《Flask Web开发》笔记——第二章 程序的基本结构

2019-01-04  本文已影响11人  鹿呀鹿呀快开门

1. 一个简单的Flask程序

一个最简单的flask应用看起来如下,这个程序命名为hello.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'hello world!'

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

对于这个应用解释如下:

 |  .. admonition:: About the First Parameter
 |
 |      The idea of the first parameter is to give Flask an idea of what
 |      belongs to your application.  This name is used to find resources
 |      on the filesystem, can be used by extensions to improve debugging
 |      information and a lot more.
 |
 |      So it's important what you provide there.  If you are using a single
 |      module, "__name__" is always the correct value.  If you however are
 |      using a package, it's usually recommended to hardcode the name of
 |      your package there.
def hello_world():
    return 'hello world'
if __name__ == '__main__':
    app.run(debug=True)

2. 当我们上网我们在干嘛

想一想我们希望在网上浏览新闻,或去购物网站买东西,又或是去某个网站填一份调查问卷。对于我们用户来讲,我们只是在浏览器中输入一串字符,然后就可以去浏览我们需要的页面,也可以在页面中输入一些信息,进行一些操作。这一切看起来是如此的简单,但我们想想,我们在进行这些操作的时候,浏览器在干什么?浏览器背后的网络在干什么?


WSGI Server 和 App交互图

这背后的逻辑,我们可以通过上面的图进行解释:

| 请求行(request line)
| 请求头(request header)
| 请求正文

请求信息的组成如下表所示,注意请求头部和请求数据之间有一个空格,这表示请求头部的结束。这里我们不去深入解释具体的参数,只是说一下每一部分都有什么作用。
请求行:用来说明请求类型,要访问的资源以及所使用的HTTP版本
请求头部:用来说明服务器要使用的附加信息
请求数据:也叫主体,可以添加任意的其他数据


请求信息格式

这以上就是我们在使用浏览器上网的过程中,在我们浏览器背后所隐藏着的动作,明白这里面的逻辑关系,有助于我们对开发web应用的理解。

3. 再看Flask程序

对于上面我们看到的"一个简单的Flask程序",当我们在浏览器上输入网址后,服务器接收到这个信息,并交给Flask程序处理,Flask根据收到的URL分配路由,如这里如果是主机后面之间是'/'(如果没有直接写出'/',会当作默认加上该符号),则将该路由下的视图函数反馈的内容作为响应主体反馈。因此,在浏览器上会显示出返回的字符串'Hello World'。
因此,我们开发的Flask应用就有两个主要内容:一是定义路由;二是定义该路由下的反馈内容。如我们前面的这个最简单Flask程序中,就包括了如何定义路由,和如何反馈内容的视图函数。
当然,围绕着这两个内容,我们还需要做更多的工作:比如如何存放数据,如何设计反馈的信息,处理不同路由之间的逻辑,设置不同权限,等等。这些都将在后面的内容中进行学习。

4. 请求-响应循环

4.1 程序和请求上下文

刚刚看到这里的时候,我是一头雾水,对于这里的上下文,完全不能够理解。在网上查了半天,也还是云里雾里,好像知道了什么,又好像什么都不知道。后来跳过这里,接着往后面学习,慢慢对上下文有了自己的一些理解。特别是这里的一篇文章,大家可以参考看一下。(https://www.jianshu.com/p/2a2407f66438
首先,我们需要对上下文这个名词进行理解。上下文的英文是Context,与其翻译为上下文,不如翻译为“语境”更贴切。对于“语境”怎么理解呢?我们设想一下如下的情形。

张三问你:“怎么样?”
你该如何回答?你可能会摸不着头脑:“什么怎么样?”
但假如你和张三刚刚完成一门考试,你可能会回答:“哦,还不错哦!”
或者你们在吃着火锅,你正尝了一口食物,你可能会回答:“太辣了!”

看到没有,同样的一句话,不同的时候,回答是不一样的。这跟说话当时的情形是紧密相关的,就是说话时候的“语境”。
那么我们这里说到Flask的上下文或者称为“语境”到底指什么具体的“语境”呢?还记得前面第二部分的WSGI Server 和 App交互图中所标出的封装environ吗?在客户端发起请求,服务器端接收到请求后,Flask将根据请求的信息创建出一个“语境”,这样,在这个语境中,所有的信息都来自与这次请求。在《Flask Web开发》这本书中,其原文:请求对象就是一个很好的例子,它封装了客户端发送的HTTP请求。
Flask有两种Context上下文:程序上下文和请求上下文。参考如下表。

Flask上下文全局变量

4.2 请求调度

什么是请求调度呢?就是当客户端发来请求的时候,Flask需要给出一个响应。但是这个响应对应的是处理该请求的视图函数,那么问题来了:如何给请求找到对应的视图函数呢?请求调度就是给请求找到对应的视图函数。
Flask是在程序的URL映射中查找请求的URL的。我们可以通过flask的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>])

从这个映射中可以看出,对应不同的路由,在映射中保留了其对应的视图函数。比如这里的index,staticuser分别是不同的视图函数。而前面的Rule对应着不同的路由。

4.3 请求钩子

请求钩子的作用是:有时候在执行请求之前或执行请求之后,需要执行一个操作。比如在查看某一个页面之前,需要先确认用户是否登录,如果没有请求钩子,要实现这个目的就比较麻烦。因此请求钩子是Flask为了这些通用功能设计的一种快捷机制。
请求钩子通过修饰器实现。Flask支持以下4种钩子:

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

4.4 响应

如前面讲过,Flask调用视图函数后,将其返回值作为响应的内容。我们在浏览器看到的页面就是响应一部分内容。
但是HTTP响应还有状态码,状态码表明该相应处理的状态。比如200表示成功处理。400表示处理无效。

上一篇 下一篇

猜你喜欢

热点阅读