
1.4 分析Flask Web程序的基本结构

在本章前面的实例文件flask1.py中,已经演示了简单Flask Web程序的功能和运行方法。在本节的内容中,将详细讲解Flask Web程序的基本结构,介绍各Flask组成部分的具体功能。
1.4.1 运行方法run()
再来看前面实例文件flask1.py中,有如下最后一行代码。

上述代码的功能是调用类flask中的方法run()在本地服务器上运行当前Flask Web程序,当前Flask Web程序的名字是app。在类flask中,方法run()的原型如下所示。

方法run()中的3个参数都是可选的,具体说明如下所示。
• host:运行当前Flask Web程序的主机名,默认值是127.0.0.1或localhost。
• port:运行当前Flask Web程序的主机对应的端口号,默认值是5000。
• debug:设置是否显示调试信息,默认值是false。如果设置为true,则表示显示调试信息。
读者在开发Flask Web程序时,建议使用如下代码将方法run()中的参数debug设置为true。

这样做的好处是,在调试运行Flask Web程序的过程中,如果代码发生了变化,那么服务器会自动快速重启并重新运行Flask Web程序,提高在此查看程序运行效果的速度。并且在代码发生异常时,会打印输出对应的调试信息,如图1-15所示。如果不将参数debug设置为true,那么在修改编写的Flask Web程序后,需要手动运行Flask Web程序,这样会降低开发效率。

图1-15 在Flask的调试窗口多次重启服务器
1.4.2 路由处理
在当前Web开发领域中,主流的第三方框架使用路由技术实现URL访问导航功能。通过路由可以直接访问某个需要的页面,而无须从主页进行导航。在Flask Web程序中,在浏览器端的客户把访问请求发送给Web服务器,Web服务器再把请求发送给Flask Web程序。为了帮助Flask Web程序确定针对每个URL请求运行哪些代码,特意在路由中保存了一个URL地址到Python函数的映射关系,这就是路由导航。Flask框架支持如下3种类型的路由导航。
(1)使用路由方法route()
在Flask框架中,通过使用路由方法route()可以将一个普通函数与特定的URL关联起来。当Web服务器收到一个URL请求时,会调用执行方法route()关联的函数返回对应的响应内容。请看下面的演示代码。

在上述代码中,方法route()定义了一个路由规则:/hello,当访问者在浏览器中输入这个URL(/hello)时,会执行与之对应的函数hello_world()。也就是说,如果用户访问如下所示的URL网址,就会执行函数hello_world(),最终会将这个函数的执行结果“我是Python”输出显示在浏览器中。

(2)路由方法add_url_rule()
在Flask框架中,还可以使用方法add_url_rule()将一个URL和函数关联起来,请看下面的演示代码。

针对上述代码,如果浏览者访问如下所示的URL网址,就会执行函数hello_world(),会在网页中输出显示这个函数的执行结果“我是Python”。

(3)将不同的URL映射到同一个函数
在Flask Web程序中,可以使用多个URL来映射同一个函数。这样在访问多个不同的URL请求时,都会返回由同一个函数产生的响应内容,也就是显示相同的执行效果。例如在下面的实例文件flask2.py中,演示了将不同的URL映射到同一个函数上的过程。
源码路径:daima\1\1-4\flask2.py

执行本实例后,在浏览器中无论是输入“http://127.0.0.1:5000/”,还是输入“http://127.0.0.1:5000/aaa”,在服务器端这两个URL请求将映射到同一个函数hello(),所以输入这两个URL地址后的执行效果一样。执行效果如图1-16所示。

图1-16 执行效果
1.4.3 处理URL参数
在Flask Web程序中,有时候URL地址中的参数是动态的,例如下面的两种URL格式。

要想获取和处理URL中传递来的参数,需要在对应处理函数的参数列表中声明变量名,具体语法格式如下所示。

这样在列表中列出变量名后,就可以在处理函数get_url_param()中引用这个变量值,并可以进一步使用从URL中传递过来的参数。
例如在下面的实例文件can1.py中,演示了给URL地址设置参数的方法。
源码路径:daima\1\1-4\can1.py

在上述代码中,使用装饰器方法route()设置了一个带有规则参数的URL。

其中URL中的参数name是一个变量,如果在浏览器中输入如下URL地址。

那么“火云邪神”将作为参数传递给hello()函数,此时函数hello_name()中的参数name被赋值为“火云邪神”。所以在浏览器中的执行效果如图1-17所示。

图1-17 执行效果
在Flask框架的URL中,除了可以使用字符串类型参数外,还可以使用如下3种类型的参数。
• int:表示整型的参数,例如“/hello/1”。
• float:表示浮点型的参数,例如“/hello/1.1”。
• path:表示使用斜杠,例如“/hello/”。
例如在下面的实例文件can2.py中,演示了给URL地址分别设置整型参数和浮点型参数的方法。
源码路径:daima\1\1-4\can2.py


运行上面的代码,如果在浏览器中输入如下所示的URL。

则会调用函数show_blog()显示响应内容,例如输入“http://localhost:5000/blog/29”后的执行效果如图1-18所示。如果在浏览器中输入如下所示的URL。

则会调用函数revision()显示响应内容,例如输入“http://localhost:5000/rev/0.5”后的执行效果如图1-19所示。

图1-18 整型参数的执行效果

图1-19 浮点型参数的执行效果
1.4.4 传递HTTP请求
在计算机应用中,HTTP协议是互联网中数据通信的基础,有如下5种传递HTTP请求的方法。
• GET:使用未加密的形式向服务器发送数据。
• POST:向服务器发送HTML表单中的数据,服务器不会缓存POST接收的数据。
• PUT:使用上传的内容替换指定的目标资源。
• HEAD:和GET方法相同,但是没有响应体。
• DELETE:删除由URL指定的目标资源。
在现实应用中,常用的两种传递HTTP请求的方法是GET和POST。在Flask框架中,默认使用GET方法。通过使用URL装饰器的参数“方法类型”,可以让同一个URL的两种请求方法都映射在同一个函数上。
在默认情况下,通过浏览器传递相关数据或参数时,都是通过GET或POST请求中包含参数来实现的。其实通过URL也可以传递参数,此时直接将数据放入URL中,然后在服务器端获取传递的数据。
例如在下面的实例文件flask3.py中,演示了使用GET请求获取URL参数的过程。
源码路径:daima\1\1-4\flask3.py


本实例演示了使用参数“方法类型”的URL装饰器实例的过程。在上述实例代码中,预先定义了GET请求要返回的页面内容字符串html_txt,在helo()函数的装饰器中提供了参数methods为GET和POST字符串列表,表示URL为“/aaa”的请求,不管是GET方法还是POST方法,都被映射到helo()函数。在helo()函数内部使用flask.request.method来判断收到的请求方法是GET还是POST,然后分别返回不同的内容。
执行本实例,在浏览器中输入“http://127.0.0.1:5000/aaa”后的效果如图1-20所示。单击“按下我发送POST请求”按钮后的效果如图1-21所示。

图1-20 执行效果

图1-21 单击“按下我发送POST请求”按钮后的效果
另外,在Flask Web程序中处理URL请求时,可以使用网页重定向方法url_for()来到指定的URL。方法url_for()的语法格式如下所示。

方法url_for()可以传递如下两个参数。
• endpoint:表示将要传递的函数名。
• **values:是关键字参数,即有多个key=value的形式参数。
方法url_for()中的每个参数对应于URL的变量部分,例如在下面的实例文件flask4.py中,演示了使用方法url_for()的过程。
源码路径:daima\1\1-4\flask4.py


在上述代码中,函数hello_user()接收来自如下URL的参数的值。

如果接收上述URL的参数是admin,则使用方法url_for()执行重定向到函数hello_admin(),即执行函数hello_admin()的功能;如果接收上述URL的参数不是admin,则使用方法url_for()执行重定向到函数hello_guest(),即执行函数hello_guest()的功能。
运行文件flask4.py,在浏览器中输入“http://127.0.0.1:5000/user/admin”后,会执行函数hello_admin(),将URL重定向到“http://127.0.0.1:5000/admin”,执行效果如图1-22所示。如果在浏览器中输入的URL的name参数不是admin,例如输入的URL是“http://127.0.0.1:5000/user/火云邪神”后,会执行函数hello_guest(),将URL重定向到“http://127.0.0.1:5000/user/”,执行效果如图1-23所示。

图1-22 执行效果

图1-23 执行效果
1.4.5 模拟实现用户登录系统
编写表单文件index.html,功能是实现一个静态HTML表单,在表单中可以输入名字,单击提交按钮后会使用POST方法将表单中的数据发送到指定的URL“http://localhost:5000/login”。文件index.html的具体实现代码如下所示。
源码路径:daima\1\1-4\index.html

编写程序文件login.py,使用POST将HTML表单数据发送将到表单标签的action子句中的URL,“http://localhost/login”会映射到login()函数。因为服务器通过POST方法接收数据,因此通过以下代码获得从表单数据传递过来的参数biaodan的值。

参数biaodan的值作为变量被传递给URL:/ success,所以会在浏览器中显示对应的欢迎消息。
文件login.py的具体实现代码如下所示。
源码路径:daima\1\1-4\login.py


首先运行Python程序,然后双击打开HTML文件后将显示一个登录表单,如图1-24所示。在表单中输入“火云邪神”并单击“登录”按钮后,表单数据“火云邪神”将作为参数被传递给/success/后面的参数name,并在页面中显示对应的欢迎信息,如图1-25所示。

图1-24 登录表单

图1-25 显示欢迎信息