python flask框架详解
Flask是一个Python编写的Web微框架,让我们可以使用Python语言快速实现一个网站或Web服务。本文参考自Flask官方文档,
英文不好的同学也可以参考中文文档
1.安装flask
pipinstallflask
2.简单上手
一个最小的Flask应用如下:
fromflaskimportFlask
app=Flask(__name__)
@app.route('/')
defhello_world():
return'HelloWorld'
if__name__=='__main__':
app.run()
代码解析:
1、首先我们导入了Flask类。该类的实例将会成为我们的WSGI应用。
2、接着我们创建一个该类的实例。第一个参数是应用模块或者包的名称。如果你使用一个单一模块(就像本例),那么应当使用name,因为名称会根据这个模块是按应用方式使用还是作为一个模块导入而发生变化(可能是‘main',也可能是实际导入的名称)。这个参数是必需的,这样Flask才能知道在哪里可以找到模板和静态文件等东西
3、然后我们使用route()装饰器来告诉Flask触发函数的URL。
4、函数名称被用于生成相关联的URL。函数最后返回需要在用户浏览器中显示的信息。
运行结果:
*ServingFlaskapp"flask_demo"(lazyloading)
*Environment:production
WARNING:Thisisadevelopmentserver.Donotuseitinaproductiondeployment.
UseaproductionWSGIserverinstead.
*Debugmode:off
*Runningonhttp://127.0.0.1:5000/(PressCTRL+Ctoquit)
访问:http://127.0.0.1:5000/
app.route(rule,options)
- rule参数表示与该函数的URL绑定。
- options是要转发给基础Rule对象的参数列表。在上面的示例中,'/'URL与hello_world()函数绑定。因此,当在浏览器中打开web服务器的主页时,将呈现该函数的输出。最后,Flask类的run()方法在本地开发服务器上运行应用程序。
app.run(host,port,debug,options)
所有参数都是可选的
- host:要监听的主机名。默认为127.0.0.1(localhost)。设置为“0.0.0.0”以使服务器在外部可用
- port:默认值为5000
- debug:默认为false。如果设置为true,则提供调试信息,可以自动重载代码并显示调试信息
- options:要转发到底层的Werkzeug服务器。
2.1调试模式
虽然flask命令可以方便地启动一个本地开发服务器,但是每次应用代码修改之后都需要手动重启服务器。这样不是很方便,Flask可以做得更好。如果你打开调试模式,那么服务器会在修改应用代码之后自动重启,并且当应用出错时还会提供一个有用的调试器。
在命令行中,如果需要打开所有开发功能(包括调试模式),那么要在运行服务器之前导出FLASK_ENV环境变量并把其设置为development:
$exportFLASK_ENV=development $flaskrun
在代码中,在运行或将调试参数传递给run()方法之前,通过将application对象的debug属性设置为True来启用Debug模式。
app.debug=True app.run() #或者 app.run(debug=True)
2.2绑定IP和端口
默认情况下,Flask绑定IP为127.0.0.1,端口为5000。我们也可以通过下面的方式自定义:
app.run(host='0.0.0.0',port=80,debug=True)
0.0.0.0代表电脑所有的IP。80是HTTP网站服务的默认端口。什么是默认?比如,我们访问网站http://www.example.com,其实是访问的http://www.example.com:80,只不过:80可以省略不写。
3.Flask路由
现代Web框架使用路由技术来帮助用户记住应用程序URL。可以直接访问所需的页面,而无需从主页导航。
Flask中的route()装饰器用于将URL绑定到函数。例如:
@app.route('/hello')
defhello_world():
return'helloworld'
在这里,URL'/hello'规则绑定到hello_world()函数。因此,如果用户访问http://localhost:5000/helloURL,hello_world()函数的输出将在浏览器中呈现。
application对象的add_url_rule()函数也可用于将URL与函数绑定,如上例所示,使用route()装饰器的目的也由以下表示:
defhello_world():
return'helloworld'
app.add_url_rule('/','hello',hello_world)
4.Flask变量规则
通过向规则参数添加变量部分,可以动态构建URL。此变量部分标记为
在以下示例中,route()装饰器的规则参数包含附加到URL'/hello'的
#!/usr/bin/python
#-*-coding:UTF-8-*-
"""
@author:chenshifeng
@file:flask_demo.py
@time:2021/03/01
"""
fromflaskimportFlask
app=Flask(__name__)
@app.route('/hello/')
defhello_name(name):
return'Hello%s!'%name
if__name__=='__main__':
app.run(debug=True)
运行,访问:http://localhost:5000/hello/chenshifeng
除了默认字符串变量部分之外,还可以使用以下转换器构建规则:
| 转换器 | 描述 |
|---|---|
| string | (缺省值)接受任何不包含斜杠的文本 |
| int | 接受正整数 |
| float | 接受正浮点数 |
| path | 类似string,但可以包含斜杠 |
| uuid | 接受UUID字符串 |
#!/usr/bin/python
#-*-coding:UTF-8-*-
"""
@author:chenshifeng
@file:flask_demo.py
@time:2021/03/01
"""
fromflaskimportFlask
app=Flask(__name__)
@app.route('/post/')
defshow_post(post_id):
#showthepostwiththegivenid,theidisaninteger
return'Post%d'%post_id
@app.route('/path/')
defshow_subpath(subpath):
#showthesubpathafter/path/
return'Subpath%s'%subpath
if__name__=='__main__':
app.run(debug=True)
4.1唯一的URL/重定向行为
以下两条规则的不同之处在于是否使用尾部的斜杠。:
@app.route('/projects/')
defprojects():
return'Theprojectpage'
@app.route('/about')
defabout():
return'Theaboutpage'
projects的URL是中规中矩的,尾部有一个斜杠,看起来就如同一个文件夹。访问一个没有斜杠结尾的URL时Flask会自动进行重定向,帮你在尾部加上一个斜杠。
about的URL没有尾部斜杠,因此其行为表现与一个文件类似。如果访问这个URL时添加了尾部斜杠就会得到一个404错误。这样可以保持URL唯一,并帮助搜索引擎避免重复索引同一页面。
5.FlaskURL构建
url_for()函数对于动态构建特定函数的URL非常有用。该函数接受函数的名称作为第一个参数,以及一个或多个关键字参数,每个参数对应于URL的变量部分。
#!/usr/bin/python
#-*-coding:UTF-8-*-
"""
@author:chenshifeng
@file:flask_demo.py
@time:2021/03/01
"""
fromflaskimportFlask,redirect,url_for
app=Flask(__name__)
@app.route('/admin')
defhello_admin():
return'HelloAdmin'
@app.route('/guest/')
defhello_guest(guest):
return'Hello%sasGuest'%guest
@app.route('/user/')
defhello_user(name):
ifname=='admin':
returnredirect(url_for('hello_admin'))
else:
returnredirect(url_for('hello_guest',guest=name))
if__name__=='__main__':
app.run(debug=True)
redirect函数用于重定向,实现机制很简单,就是向客户端(浏览器)发送一个重定向的HTTP报文,浏览器会去访问报文中指定的url。
运行
打开浏览器并输入URL-http://localhost:5000/user/admin
HelloAdmin
在浏览器中输入以下URL-http://localhost:5000/user/mvl
HellomvlasGuest
6.FlaskHTTP方法
Web应用使用不同的HTTP方法处理URL。当你使用Flask时,应当熟悉HTTP方法。缺省情况下,一个路由只回应GET请求。可以使用route()装饰器的methods参数来处理不同的HTTP方法:
| 方法 | 描述 |
|---|---|
| GET | 以未加密的形式将数据发送到服务器,最常见的方法。 |
| HEAD | 和GET方法相同,但没有响应体。 |
| POST | 用于将HTML表单数据发送到服务器,POST方法接收的数据不由服务器缓存。 |
| PUT | 用上传的内容替换目标资源的所有当前表示。 |
| DELETE | 删除由URL给出的目标资源的所有当前表示。 |
默认情况下,Flask路由响应GET请求。但是,可以通过为route()装饰器提供方法参数来更改此首选项。
为了演示在URL路由中使用POST方法,首先让我们创建一个HTML表单,并使用POST方法将表单数据发送到URL。
将以下脚本另存为login.html
EnterName:
运行以下代码
fromflaskimportFlask,redirect,url_for,request
app=Flask(__name__)
@app.route('/success/')
defsuccess(name):
return'welcome%s'%name
@app.route('/login',methods=['POST','GET'])
deflogin():
ifrequest.method=='POST':
user=request.form['nm']
returnredirect(url_for('success',name=user))
else:
user=request.args.get('nm')
returnredirect(url_for('success',name=user))
if__name__=='__main__':
app.run(debug=True)
在浏览器中打开login.html,在文本字段中输入name,然后单击提交。
表单数据将POST到表单标签的action子句中的URL。
http://localhost/login映射到login()函数。由于服务器通过POST方法接收数据,因此通过以下步骤获得从表单数据获得的“nm”参数的值:
表单数据将POST到表单标签的action子句中的URL。
user=request.form['nm']
它作为变量部分传递给'/success'URL。浏览器在窗口中显示welcome消息。
在login.html中将方法参数更改为'GET',然后在浏览器中再次打开它。服务器上接收的数据是通过GET方法获得的。通过以下的步骤获得'nm'参数的值:
User=request.args.get('nm')
这里,args是包含表单参数对及其对应值对的列表的字典对象。与'nm'参数对应的值将像之前一样传递到'/success'URL。
7.Flask模板
在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本.
- 模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
- 使用真实值替换变量,再返回最终得到的字符串,这个过程称为'渲染'
- Flask是使用Jinja2这个模板引擎来渲染模板
使用模板的好处
视图函数只负责业务逻辑和数据处理(业务逻辑方面)而模板则取到视图函数的数据结果进行展示(视图展示方面)代码结构清晰,耦合度低
使用render_template()方法可以渲染模板,你只要提供模板名称和需要作为参数传递给模板的变量就行了。
Flask会在templates文件夹内寻找模板。因此,如果你的应用是一个模块,那么模板文件夹应该在模块旁边;如果是一个包,那么就应该在包里面:
情形1:一个模块:
/application.py /templates /hello.html
情形2:一个包:
/application /__init__.py /templates /hello.html
示例代码:
fromflaskimportFlask,render_template
app=Flask(__name__)
@app.route('/')
defindex():
my_int=18
my_str='curry'
my_list=[1,5,4,3,2]
my_dict={
'name':'durant',
'age':28
}
#render_template方法:渲染模板
#参数1:模板名称参数n:传到模板里的数据
returnrender_template('hello.html',
my_int=my_int,
my_str=my_str,
my_list=my_list,
my_dict=my_dict)
if__name__=='__main__':
app.run(debug=True)
Title 我是模板
{{my_int}}
{{my_str}}
{{my_list}}
{{my_dict}}
模板的list数据获取
{{my_list[0]}}
{{my_list.1}}
字典数据获取
{{my_dict['name']}}
{{my_dict.age}}
算术运算
{{my_list.0+10}}
{{my_list[0]+my_list.1}}