一、安装
二、快速上手 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from flask import Flaskfrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def hello_world (): return "<p>Hello, World!</p>" if __name__ == '__main__' : app.run(port=5000 , debug=True )
加入动态路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from flask import Flaskfrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def hello_world (): return "<p>Hello, World!</p>" @app.route("/user/<name>" ) def user (name ): return "<p>Hello, {}!</p>" .format (name) if __name__ == '__main__' : app.run(port=5000 , debug=True )
三、请求-响应循环 想要理解Flask的工作模式,就需要理解:请求-响应循环。
请求 请求对象,封装了客户端发出的HTTP请求中的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from flask import Flask, requestfrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): user_agent = request.headers.get('User-Agent' ) return "<p>your brower is {}</p>" .format (user_agent) if __name__ == '__main__' : app.run(port=5000 , debug=True )
响应 我们可以创建一个响应对象,然后设置cookie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from flask import Flask, request, make_responsefrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): user_agent = request.headers.get('User-Agent' ) return "<p>your brower is {}</p>" .format (user_agent) @app.route("/test" ) def test (): response = make_response('<h1>This document carries a cookies!</h1>' ) response.set_cookie('answer' , '42' ) return response if __name__ == '__main__' : app.run(port=5000 , debug=True )
HTTP响应中很重要的一部分是响应状态码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from flask import Flask, requestfrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): user_agent = request.headers.get('User-Agent' ) return "<p>your brower is {}</p>" .format (user_agent) @app.route("/test1" ) def test1 (): return '<h1>Bad Request</h1>' , 400 if __name__ == '__main__' : app.run(port=5000 , debug=True )
响应有种特殊的类型称为重定向,用以加载新页面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from flask import Flask, request, redirectfrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): user_agent = request.headers.get('User-Agent' ) return "<p>your brower is {}</p>" .format (user_agent) @app.route("/test2" ) def test2 (): return redirect('https://www.bytecat.net' ) if __name__ == '__main__' : app.run(port=5000 , debug=True )
四、响应的进阶:模板 视图函数的作用很明确,即生成请求的响应。在前面的例子中视图函数既包含了业务逻辑,也包含了表现逻辑(html),这种模式对于最简单的请求来说是够了,但是对于大型应用来说是不合理的,因为将业务逻辑和表现逻辑混在一起会导致代码难以理解和维护。 为了提高应用的可维护性,我们需要做一些改进,把表现逻辑移到模板中。
渲染模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from flask import Flask, render_templatefrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): return render_template('index.html' ) if __name__ == '__main__' : app.run(port=5000 , debug=True )
默认情况下,Flask会在应用的templates子目录中寻找模板。所以需要新建templates子目录,将模板保存在里面。
模板传参 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from flask import Flask, render_templatefrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): return render_template('index.html' ) @app.route("/user/<name>" ) def user (name ): return render_template('user.html' , name=name) if __name__ == '__main__' : app.run(port=5000 , debug=True )
模板user.html内容如下
1 <h1>hello {{name}}!</h1>
在模板中使用的 结构表示一个变量,这是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取。 Jinja2模板引擎能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。下面是一些示例。
1 2 3 <p>A value from a dictionary: {{ mydict['key'] }}. </p> <p>A value from a list: {{ mylist[3] }}. </p> <p>A value from an object's method: {{ myobj.somemethod() }}. </p>
变量的值可以使用过滤器修改。过滤器添加在变量名之后,二者之间以竖线分隔。例如:
1 <h1>hello {{name|capitalize}}!</h1>
这个模板把name变量的值变成首字母大写的形式。下面是Jinja2提供的部分常用的过滤器。
过滤器名
说明
safe
渲染值时不转义
capitalize
把值的首字母转换成答谢,其他字母转换成小写
lower
把值转换成小写形式
upper
把值转换成大写形式
title
把值中每个单词的首字母都转换成大写
trim
把值的首尾空格去掉
striptags
渲染之前把值中所有的html标签都删掉
注意 :千万别再不可信的值上使用safe过滤器,例如用户在表单中输入的文本.
控制结构 Jinja2提供了多种控制结构,可用来改变模板的渲染流程。
(1)条件判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from flask import Flask, render_templatefrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): return render_template('index.html' ) @app.route("/user/<name>" ) def user (name ): if name == 'bytecat' : return render_template('user.html' , name=name) else : return render_template('user.html' ) if __name__ == '__main__' : app.run(port=5000 , debug=True )
user.html改写如下
1 2 3 4 5 {% if name %} <h1>hello {{ name|capitalize }}!</h1> {% else %} <h1>hello, Stranger!</h1> {% endif %}
(2)循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from flask import Flask, render_templatefrom flask_cors import CORSdef create_app (): app = Flask(__name__) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): return render_template('index.html' ) @app.route("/user" ) def user (): names = ['tom' , 'alice' , 'victor' , 'alex' , 'eric' ] return render_template('user.html' , names=names) if __name__ == '__main__' : app.run(port=5000 , debug=True )
user.html改写如下
1 2 3 4 5 <ul> {% for name in names %} <li>{{ name }}</li> {% endfor %} </ul>
五、其他 静态文件 web应用不是仅由python代码和模板组成,多数应用还会使用静态文件,例如模板中html代码引用的图像、js和css。 默认设置下,Flask在应用根目录中名为static的子目录中寻找静态文件。如果需要,可在static文件夹中使用子文件夹存放文件。 下面的示例展示了如何在模板中引入favicon.ico图标,这个图标会显示在浏览器的地址栏中。
app.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from flask import Flask, render_templatefrom flask_cors import CORSimport osBASE_PATH: str = os.path.dirname((os.path.abspath(__file__))) print (BASE_PATH)def create_app (): app = Flask( __name__, static_folder=f"{BASE_PATH} /static" , template_folder=f"{BASE_PATH} /templates" ) CORS(app, supports_credentials=True ) return app app = create_app() @app.route("/" ) def index (): return render_template('index.html' ) if __name__ == '__main__' : app.run(port=5000 , debug=True )
index.html
1 2 3 4 5 6 7 8 {% block head %} <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon"> <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon"> {% endblock %} {% block content %} <h1>hello world!</h1> {% endblock %}