深入学习Flask框架之简单创建一个项目
Posted fangtaoa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入学习Flask框架之简单创建一个项目相关的知识,希望对你有一定的参考价值。
在前面一篇讲了如何创建一个虚拟环境,今天这一篇就来说说如何创建一个简单的Flask项目。关于Flask的具体介绍就不详细叙述了,我们只要知道它非常简洁、灵活和扩展性强就够了。它不像Django那样集成度特别高。Flask只是一个内核,默认依赖于两个外部库: Jinja2 模板引擎和 Werkzeug WSGI 工具集,其他很多功能都是以扩展的形式进行嵌入使用。
一、一个简单的小例子
创建一个Flask项目的步骤:
1.导入Flask类
2.创建程序实例
3.定义视图(函数)
4.启动服务器
1 from flask import Flask
2
3 app = Flask(__name__)
4
5
6 @app.route(‘/‘)
7 def index():
8 return ‘Hello Flask‘
9
10
11 if __name__ == "__main__":
12 app.run(debug=True)
二、剖析上述7行代
导入Flask模块的那一行就不说了。我们来剖析一下app = Flask(__name__)这一行。我们可以传入其他类型的参数么?如数值,如标准模块名或其他的。
1.app = Flask(__name__)
(1).Flask()能不能传入数字?
如果传入的数字,那么会产生一个错误:AttributeError: ‘int‘ object has no attribute ‘startswith‘,这个错误说明传入的必须是字符串,因为只有字符串类型才有startswith()方法。
(2).Flask()能不能传入标准模块名?
如果传入的一个标准模块名,如"re", 那么在浏览器的地址栏中输入:127.0.0.1:5000/static/index.html,此时程序会到re模块的路径(/usr/lib/pythonx.x/)下查找有没有这个文件。注意,我们一般不应该去修改python标准模块的目录结构的!所以我们传入的参数一般不使用标准模块名,要么使用__name__,要么使用一个字符串(但不能是标准模块名)。
2.视图部分
1 @app.route(‘/‘)
2 def index():
3 return ‘Hello Flask‘
在Flask中,每个视图的作用都是与一个指定的url相对应,即当浏览器发送一个请求过来之后,就会有一个视图返回响应信息给浏览器。那么问题来了:一个url可以对应多个视图么, 如何给视图传入参数以及状态码有什么用?
(1). 一个URL可以对应多个相同的视图么?
一个URL是不能对应多个相同的视图,但是一个URL,可以对应不同的视图。因为一个URL只能有一个响应信息!但是为什么一个URL可以有多个不同的视图呢?因为每个URL的请求方法可能是不一样的。
1 from flask import Flask
2
3 app = Flask(__name__)
4
5
6 @app.route(‘/‘, methods=[‘POST‘, ‘PUT‘])
7 def index1():
8 return ‘这是index1‘
9
10
11 @app.route(‘/‘, methods=[‘DELETE‘])
12 def index2():
13 return ‘这是index2‘
14
15
16 # 当在浏览器中输入127.0.0.1:5000/时,会触发index3(),因为这个试图有的请求方法有GET,
17 # 如果是URL会向服务器提交数据的话,那么使用的方法是POST,此时会根据url_map来按顺序选择
18 # 试图来进行响应
19 @app.route(‘/‘, methods=[‘GET‘, ‘POST‘])
20 def index3():
21 return ‘这是index3‘
22
23
24 if __name__ == "__main__":
25 print(app.url_map) # url_map是url与试图的映射关系
26 app.run(debug=True)
(2). 如何给视图传入参数?
给视图传入参数的url格式是:"/xxxx/<type: arg>"。
使用<类型:参数>,这样子就可以往视图中传入参数了。在Flask中有6中定义的类型,每种类型都有对应的转换器(Converter),常用的转换器是:参数的默认类型是str类型。
1 DEFAULT_CONVERTERS = {
2 ‘default‘: UnicodeConverter,
3 ‘string‘: UnicodeConverter,
4 ‘any‘: AnyConverter,
5 ‘path‘: PathConverter,
6 ‘int‘: IntegerConverter,
7 ‘float‘: FloatConverter,
8 ‘uuid‘: UUIDConverter,
9 }
比如:
1 # 视图parse_args携带两个参数,一个是int类型,另一个是str类型
2 # 此时组成的URL格式是:127.0.0.1:5000/args/111abc,
3 # 也就是说args/后面的参数是整数在前,字符串在后,必须是两个都存在。
4 @app.route(‘/args/<int:int_arg><string:str_arg>‘)
5 def parse_args(int_arg, str_arg):
6 return ‘该URL携带的参数是:%s和%s‘ % (int_arg, str_arg)
(3). 状态码有什么用?
在程序中,我们可以自定义状态码,也可以使用HTTP协议规定的状态码。
自定义状态码的目的是为了实现前后端的数据交互!如在js脚本中使用ajax去请求服务器的数据时,如果请求的数据不存在,那么后端就返回一个错误码和错误信息,这样只要判断错误码就知道错误的结果了!比如检验用户名和密码的时候就会用到。
HTTP规定的状态码可以在视图中使用abort(status_code)函数把想要返回的状态码返回给客户端。这条语句就像raise语句。当abort函数执行后,程序就不会再往下执行了。不过abort()只能抛出HTTP协议规定的状态码,不能抛出自定义的状态码。
1 @app.route(‘/status‘)
2 def resp_status():
3 # 当视图返回时,响应体被渲染到浏览器中,状态码由浏览器获得,这个状态码可以是任意的。
4 return ‘响应成功!‘, 600
如果当发生标准错误(如404, 500...)了,有没有什么更好的解决方案呢?
在Flask中,@app.errorhandlers()装饰器是一个很好的选择,当发生诸如404, 500这样的错误时,我们可以自定义错误的信息,如果返回一个好看的页面,而不是返回专业术语,这些术语又不是给用户看的!
1 @app.route(‘/status‘)
2 def resp_status():
3 # 当返回时,响应体被渲染到浏览器中,状态码由浏览器获得,
4 # 这个状态码可以是任意的。
5 abort(500)
6 return ‘响应成功!‘, 600
7
8
9 @app.errorhandler(500)
10 def error_500(e):
11 return ‘不好意思,服务器出了点小毛病!请稍后再试!‘
在浏览器的地址栏中输入:127.0.0.1:5000/status 之后。先执行resp_stauts视图,当执行到abort语句时,会抛出500错误,此时因为在程序中定义了状态码为500的处理视图,也就是说程序会自动执行error_500视图,然后把响应体返回给浏览器。
(4). 如何实现重定向功能?
重定向也算是一个比较常见的功能,比如某宝,某东每年都会有很多活动,那么在剁手节的时候很多商品可能很快就会被剁走了。此时,如果当用户没有找到他们想要的东西时,我们不应该直接报告错误吧,而是应该把用户一步步的引诱到其他的剁手活动中,这就是重定向功能!
1 @app.route(‘/redirect‘)
2 def redirect_resp():
3 # 重定向到百度去
4 # 但是这种方式不是很好,因为如果每个试图都用重定向的话,会写很多相同的代码,扩展性差
5 # 那有没有更好的办法?
6 return ‘你们都是重定向过来的!‘
7
8
9 @app.route(‘/xxx‘)
10 def redirect_url():
11 # 当地址栏中是127.0.0.1:5000/xxx时,会重定向到redirect_resp试图去
12 # 然后redirect_base又重定向到百度。
13 # 这实际上是一个反向解析的过程,即通过试图去匹配url, 并响应.
14 # url_for()中的参数是由试图名组成的字符串,使用url_for的扩展性特别强。
15 return redirect(url_for(‘redirect_resp‘))
以上是关于深入学习Flask框架之简单创建一个项目的主要内容,如果未能解决你的问题,请参考以下文章
深入浅出Flask(10): H-ui前端框架入门之资源定位