# 一、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 模板继承 *

  • 父类 base.html
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>

  • 子类 index.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 }}
{# {{ read_md('demo.md') | 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) # 调用hello_world(),在浏览器网页输出hello world

实验 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__) # 初始化Flask实例


@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) # 调用hello_world(),在浏览器网页输出hello world

# 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:在浏览器中上传本地图片与文字信息并展示

  • 标签用于创建**供用户输入**的 HTML 表单。
  • 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)

# 使用Opencv转换一下图片格式和名称
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

更新于

请我喝[奶茶]~( ̄▽ ̄)~*

ayanamisaki 微信支付

微信支付

ayanamisaki 支付宝

支付宝