# 一、Flask 简介
# 1. Web 应用框架
- 一款非常流行的 轻量级 Python Web 应用框架
- Web 应用框架:用于进行 Web 开发的一套软件架构,提供了一套开发和部署网站的方式
- 页面:以 HTML 的形式发送到浏览器中
- 发送 HTML 到浏览器的应用:Web 应用
- Web 框架的目的:向程序员隐藏了处理 HTTP 请求和响应相关的基础代码
- e.g. 点外卖,消费者只需要关注 “我想吃什么” 这样的高层逻辑,而无需关注下单后骑手如何分配、商家如何接单、菜品如何制作、骑手如何配送等等基础问题
- 课后阅读 1:什么是 Web 框架?
# 2. 路由与模板
# ①路由 route:业务逻辑
- 如何将请求的 URL 映射到处理它的代码上?
- 即:怎样将网址与逻辑处理函数相关联起来?
- 答:Flask 将一个函数和请求的 URL 关联起来的标准方法是通过使用 route () 装饰器
1 2 3
| @app.route('/users/<id:int>/') def display_user(id):
|
# ②模板 templates:页面逻辑
- 怎样动态地生成 HTML?
- 即:怎样动态地构造请求的 HTML 返回给客户端
- (HTML 中带有计算得到的值或者从数据库中取出来的信息)
- 怎样:指的是网页表层的显示,而不是指底层具体是怎样实现的(底层机制)
- 模板:简单来说就是一个其中包含占位变量表示动态的部分的文件,模板文件在经过动态赋值后,返回给用户
- 可以理解为渲染
- 模板:书架,第一层放语文书,第二层放数学书,第三层放计算机课本
- 我们要做的是把对应的书放在对应的层
- templates 模板 be like:
语文书 1 |
语文书 2 |
语文书 3 |
数学书 1 |
数学书 2 |
数学书 3 |
计算机课本 1 |
计算机课本 2 |
计算机课本 3 |
- 渲染后be like:
《论语》 |
《大学》 |
《中庸》 |
《高等数学》 |
《线性代数》 |
《离散数学》 |
《D3 数据可视化》 |
《大数据导论》 |
《数据结构》 |
课后阅读 2:快速入门 ——Flask 文档
# ③jinjia2 语句
- 语法块:
![image-20220513121553829]()
1 2 3 4 5 6 7 8 9 10 11 12
| {# jinjia2模板不能单独使用,只能跟脚本配合使用。 #}
{% if ansible_distribution == "CentOS" %} WelCome to {{ ansible_distribution }} - {{ ansible_distribution_version }} 空闲内存大小 {{ ansible_memfree_mb * 1000 }} {% else %} Welcome to China {% endif %}
{% for i in ansible_date_time %} {{ i }} {% endfor %}
|
课后阅读 3:jinjia2 - 块 block
④jinjia2 模板继承 *
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> {% block head %} <meta charset="UTF-8"> <title> {% block title %} {% endblock title %} </title> {% block static_file %} {% endblock static_file %} {% block CSS_change %} {% endblock CSS_change %} {% block js %} {% endblock js %} {% endblock head %} </head> <body>
<header> {% block header %} {% endblock header %} </header> <div> {% block content %} {% endblock content %} </div> <footer> {% block footer %} <h3> <a href="https://blog.csdn.net/time_money" target="_blank"> Python小明 </a> </h3> {% endblock footer %} </footer>
</body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| {% extends 'base.html' %}
{% block title %}index{% endblock title %}
{% block content %} {% autoescape false %} {{ data1 }} {% endautoescape %} {{ data2 | safe }} {{ data3 | md |safe }} { <nav> <a href="{{ url_for('.services') }}">Services</a> <a href="{{ url_for('.about') }}">About</a> </nav> {% endblock content %}
|
# 3. 项目结构
1 2 3
| | - templates //jinjia2模板 | - static //css,js 图片等静态文件 | - server.py //主程序
|
1 2 3 4 5 6 7 8 9 10 11
| // Linux ↓ mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py
// Windows ↓ mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates echo HelloWorld/server.py
|
P.S. 手动创建也可以
** 延申
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| | - app //程序包 | - templates //jinjia2模板 |- static //css,js 图片等静态文件 | - main //py程序包 ,可以有多个这种包,每个对应不同的功能 | - __init__.py |- errors.py |- forms.py |- views.py |- __init__.py | - email.py //邮件处理程序 |- models.py //数据库模型 |- migrations //数据迁移文件夹 |- tests //单元测试 |- __init__.py |- test*.py //单元测试程序,可以包含多个对应不同的功能点测试 |- venv //虚拟环境 |- requirements.txt //列出了所有依赖包以及版本号,方便在其他位置生成相同的虚拟环境以及依赖 |- config.py //全局配置文件,配置全局变量 |- manage.py //启动程序
|
# 二、Flask 基础实验
# 1. 基本原理
第一部分,初始化:所有的 Flask 都必须创建程序实例,
web 服务器使用 wsgi 协议,把客户端所有的请求都转发给这个程序实例
程序实例是 Flask 的对象,一般情况下用如下方法实例化
Flask 类只有一个必须指定的参数,即程序主模块或者包的名字
__name__是系统变量,该变量指的是本 py 文件的文件名
1 2
| from flask import Flask app = Flask(__name__)
|
_ 第二部分,路由和视图函数:
客户端发送 url 给 web 服务器,web 服务器将 url 转发给 flask 程序实例_
_ 程序实例需要知道对于每一个 url 请求启动那一部分代码,所以保存了一个 url 和 python 函数的映射关系。
处理 url 和函数之间关系的程序,称为路由
在 flask 中,定义路由最简便的方式,是使用程序实例的 app.route 装饰器,把装饰的函数注册为路由_**
1 2 3
| @app.route('/') def hello_world(): return 'hello world'
|
第三部分:程序实例用 run 方法启动 flask 集成的开发 web 服务器
name == 'main’是 python 常用的方法,表示只有直接启动本脚本时候,才用 app.run 方法
如果是其他脚本调用本脚本,程序假定父级脚本会启用不同的服务器,因此不用执行 app.run ()
服务器启动后,会启动轮询,等待并处理请求。轮询会一直请求,直到程序停止。
_设置 debug 模式:默认情况下,flask 的 debug 模式是关闭的。当开启了 debug 模式后,当代码出现错误,错误提示会在终端中显示。debug 模式只在开发模式下开启,因为 debug 模式会带来非常大的安全隐患。
flask 开启 debug 模式 app.run (debug=True)
1 2 3
| if __name__ == '__main__': print("yes") app.run(debug=True)
|
实验 1:理解 Flask 工作原理
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 26
| from flask import Flask
app = Flask(__name__)
@app.route('/') def hello_world(): return 'hello world'
@app.route('/user') def hello_user(): return 'hello user '
@app.route('/user/<userid>') def hello_user_id(userid): return 'hello user ' + userid
if __name__ == '__main__': print("yes") app.run(debug=True)
|
# 2. 使用 templates 模板
实验 2:在浏览器中显示 a+b 的计算值
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>实验2</title> </head> <body> {{ tag }} <br> {{ tag(99,1) }} </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from flask import Flask from flask import render_template
app = Flask(__name__)
def a_b_sum(a,b): return a+b
@app.route("/") def index(): return render_template("index.html", tag=a_b_sum)
app.run(debug=True)
|
![image-20220513124327705]()
# 3. 综合实践
实验 3:在浏览器中上传本地图片与文字信息并展示
-
- multipart/form-data:既可以上传文件等二进制数据,也可以上传表单键值对,只是最后会转化为一条信息;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body>
<form action="demo-form.php"> First name: <input type="text" name="FirstName" value="Mickey"><br> Last name: <input type="text" name="LastName" value="Mouse"><br> <input type="submit" value="提交"> </form>
</body> </html>
|
![image-20220513124500873]()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>实验3</title> </head> <body> <h1>实验3:在浏览器中上传本地图片与文字信息并展示</h1> <form enctype = 'multipart/form-data' method = 'POST'> <input type="file" name = "upload_file"/> <br> <i>请输入图片主色调:</i>
<input type = "text" name = "input_text"/> <input type="submit" value="上传"/> </form> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Flask上传图片演示</title> </head> <body> <h1>实验3:在浏览器中上传本地图片与文字信息并展示</h1> <form enctype = 'multipart/form-data' method = 'POST'> <input type="file" name = "upload_file"/> <br> <i>请输入图片主色调:</i>
<input type = "text" name = "input_text"/> <input type="submit" value="上传"/> </form>
<h1>图片的主色调是:{{userinput}}!</h1> <img src="{{url_for('static',filename='./images/test.jpg')}}" height="400" alt="你的图片被外星人劫持了~~"/> </body> </html>
|
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 26 27 28 29 30 31 32 33 34 35
| from flask import Flask, render_template, request from werkzeug.utils import secure_filename import os import cv2
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'bmp'])
def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
app = Flask(__name__)
@app.route('/', methods=['POST', 'GET']) def upload(): if request.method == 'POST': f = request.files['upload_file'] user_input = request.form.get("input_text") basepath = os.path.dirname(__file__) upload_path = os.path.join(basepath, 'static/images', secure_filename(f.filename)) f.save(upload_path)
img = cv2.imread(upload_path) cv2.imwrite(os.path.join(basepath, 'static/images', 'test.jpg'), img)
return render_template('upload_ok.html', userinput=user_input)
return render_template('upload.html')
if __name__ == '__main__': app.run(debug=True)
|
![image-20220513124423839]()
课后阅读 1:什么是 Web 框架?
课后阅读 2:快速入门 ——Flask 文档
课后阅读 3:jinjia2 - 块 block