Flask学习

Flask 是一个用 Python 编写的轻量级 Web 应用框架,基于 WSGI(Web Server Gateway Interface)和 Jinja2 模板引擎,旨在帮助开发者快速、简便地创建 Web 应用。Flask 被称为”微框架”,因为它使用简单的核心,用扩展增加其他功能。

特点:

  • 轻量级和简洁:Flask 是一个微框架,提供了最基本的功能,不强制使用任何特定的工具或库。核心是简单而灵活的,允许开发者根据需要添加功能。
  • 灵活性:提供了基本的框架结构,但没有强制性的项目布局或组件,开发者可根据自己的需求自定义。
  • 可扩展性:允许通过插件和扩展来添加功能。许多常见的功能,如表单处理、数据库交互和用户认证,都可以通过社区提供的扩展来实现。
  • 内置开发服务器:内置了一个开发服务器,方便在本地进行调试和测试。
  • RESTful 支持:支持 RESTful API 的开发,适合构建现代的 Web 服务和应用程序。

组成:

  • Flask 应用实例:Flask 的核心是应用实例,通过创建 Flask 对象来初始化应用。
  • 路由和视图函数:路由将 URL 映射到视图函数,视图函数处理请求并返回响应。
  • 模板系统:Flask 使用 Jinja2 模板引擎来渲染 HTML 页面,将数据动态插入到页面中。
  • 请求和响应:Flask 处理 HTTP 请求并生成响应,支持多种 HTTP 方法(如 GET、POST)。

Flask安装

pip安装FLask(Flask需要Python3.6以上版本,可使用python --version检查Python版本):

1
2
3
4
5
6
7
8
9
10
11
12
pip install Flask

# 安装成功后,可以通过一下命令验证Flask安装是否成功:
pip show Flask

Home-page:
Author:
Author-email:
License:
Location: d:\miniconda\conda_base\envs\flaskenv\lib\site-packages
Requires: blinker, click, importlib-metadata, itsdangerous, Jinja2, Werkzeug
Required-by: Flask-Bcrypt, Flask-Cors, Flask-JWT-Extended, Flask-Login, Flask-SQLAlchemy

Flask第一个应用

通过Pycharm创建:

文件->新建项目:

打开项目中的app.py文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 从Flask包中引入Flask类
from flask import Flask, request

# 使用Flask类创建一个app对象
# __name__:代表当前app.py这个模块
# 1. 以后出现bug,可帮助我们快速定位
# 2. 对于寻找模板文件,有一个相对路径
app = Flask(__name__)

# 创建一个路由和视图函数的映射
@app.route('/')
def hello_world():
return 'Hello Moon马也!'

if __name__ == '__main__':
app.run()

运行后控制台显示:

1
2
3
4
5
6
7
8
9
FLASK_APP not set
FLASK_ENV = development
FLASK_DEBUG = 0
In folder D:/PyCharm2020/pythonProject/FlaskStudy
D:\miniconda\conda_base\envs\FlaskEnv\python.exe -m flask run
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit

打开浏览器,访问http://127.0.0.1:5000或localhost:5000:

Flask配置

  1. debug模式:
    开启debug模式后,只要修改代码后保存,就会自动重新加载,不需要手动重启项目
    如果开发的时候,出现bug,如果开启了debug模式,在浏览器上就可以看到出信息

  2. 修改host:
    主要作用:就是让其他电脑能访问到我电脑上的flask项目

  3. 修改端口号port:
    主要的作用:如果5000端口被其他程序占用了,那么可以通过修改port监听的端口号

URL与视图映射

url: http[80]/https[443]://www.qq.com:443/path
url与视图:path与视图

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
# 创建一个路由和视图函数的映射
# https://www.baidu.com
# /home/user/xx
@app.route('/')
def hello_world():
return 'Hello Moon马也!'


@app.route('/profile')
def profile():
return '我是个人中心!'
@app.route('/blog/list')
def blog_list():
return '我是博客列表!'


# 带参数的url:将参数固定到了path中 类型定义:string/int/float/path/uuid/any
@app.route('/blog/<int:blog_id>')
def blog_detail(blog_id):
return "您访问的博客是:%s" % blog_id

# 查询字符串的方式传参
# /book/list:会给我返回第一页的数据
# /book/list?page=2:获取第二页的数据
@app.route('/book/list')
def book_list():
# request.args:类字典类型
page = request.args.get("page", default=1, type=int)
return f"您获取的是第{page}页的图书列表!"

Jinja2模板

访问对象属性

访问方式:

  1. {{对象/字典.属性名}}
  2. {{字典[属性名]}}
1
2
3
4
5
6
7
8
9
10
11
12
13
class User:
def __init__(self, username, email):
self.username = username
self.email = email

@app.route('/')
def hello_world():
user = User(username="马也", email="970640814@qq.com")
person = {
"username": "木易",
"email": "1614028745@qq.com"
}
return render_template("index.html", user=user, person=person)
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>马也首页</title>
</head>
<body>
<h1>马也首页</h1>
<div>{{ user.username }} / {{ user.email }}</div>
<div>{{ person['username'] }} / {{ person.username }}</div>
</body>
</html>

效果:

过滤器

语法:{{变量|过滤器名}}

1
2
3
4
5
6
7
8
9
10
11
12
# 自定义函数
def datetime_format(value, format='%Y年%m月%d日 %H:%M'):
return value.strftime(format)

# 注册过滤器
app.add_template_filter(datetime_format, "dformat")

@app.route('/filter')
def filter_demo():
user = User(username="木马也", email="970640814@qq.com")
mytime = datetime.now()
return render_template("filter.html", user=user, mytime=mytime)
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤器使用demo</title>
</head>
<body>
<div>{{ user.username }}-{{ user.username|length }}</div>
<div>{{ mytime|dformat }}</div>
</body>
</html>

效果:

控制语句

1
2
3
4
5
6
7
{% if 判断语句 %}
{% elif 判断语句 %}
{% else %}
{% endif %}

{% for item in items %}
{% endfor %}
1
2
3
4
5
6
7
8
9
10
11
@app.route('/control')
def control_statement():
age = 22
books = [{
"name": "三国演义",
"author": "罗贯中"
}, {
"name": "水浒传",
"author": "施耐庵"
}]
return render_template("control.html", age=age, books=books)
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>
<meta charset="UTF-8">
<title>控制语句</title>
</head>
<body>
{% if age > 18 %}
<div>您已满18岁,可以进入网吧!</div>
{% elif age==18 %}
<div>您刚满18岁,需要父母陪同才能进入!</div>
{% else %}
<div>您未满18岁,不能进入网吧!</div>
{% endif %}

{% for book in books %}
<p>图书名称:{{ book.name }}</p>
<p>作者:{{ book.author }}</p>
{% endfor %}

</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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title%}{% endblock %}</title>
</head>
<body>
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">新闻</a></li>
</ul>
{% block body%}
{% endblock %}
<footer>这是底部的标签</footer>
</body>
</html>
========================================================================================
{% extends "base.html" %}

{% block title %}
语句
{% endblock %}

{% block body %}
语句
{% endblock %}

加载静态文件

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/my.js') }}"></script>
</head>
<body>
<img src="{{ url_for('static', filename='images/ironman.jpg') }}" alt="">
</body>
</html>