Flask框架

目录

一、Flask 框架基础认知

(一)Flask 框架核心特性

(二)核心依赖库

二、Flask 的安装与首个应用搭建

(一)安装 Flask

(二)创建首个 Flask 应用

1. 代码示例

2. 代码详细解析

(三)运行 Flask 应用

三、Flask 路由系统深入解析

(一)路由基本概念

(二)动态路由

1. 基本概念

2. 代码示例

3. 代码解析

4. 动态参数类型指定

(三)支持多种 HTTP 请求方法

1. 代码示例(仅允许 POST 请求)

2. 代码解析

3. 处理多种请求方法示例

四、Jinja2 模板引擎的应用

(一)模板引擎基本作用

(二)基础模板渲染

1. 模板文件示例(greet.html)

2. 视图函数代码

3. 代码解析

(三)模板继承与块

1. 基础模板(base.html)

2. 子模板(index.html)

3. 代码解析

五、Flask 表单处理与验证

(一)表单处理扩展库 Flask-WTF

(二)安装 Flask-WTF

(三)创建简单表单示例

1. 代码示例(app.py)

2. 代码解析

3. 模板文件(index.html)

4. 模板代码解析

(四)常见表单验证规则

六、Flask 项目结构与部署

(一)典型项目结构

(二)Flask 应用部署

1. 使用 Gunicorn 部署

(1)安装 Gunicorn

(2)启动应用

2. 结合 Nginx 作为反向代理

(1)安装 Nginx

(2)配置 Nginx

七、简单博客应用案例实践

(一)项目结构

(二)代码实现

1. app.py代码

2. 代码解析

3. 模板文件(index.html)

4. 模板代码解析

(三)运行博客应用

(四)注意事项

八、Flask 框架总结与扩展建议

(一)核心优势总结

(二)扩展学习方向

(三)实践建议


一、Flask 框架基础认知

(一)Flask 框架核心特性

Flask 是基于 Python 语言开发的轻量级 Web 框架,被称作 “微框架”,其设计理念聚焦于简洁性、灵活性与易用性。它具备以下关键特性:

  • 轻量简洁:核心功能精简化,不强制规定复杂的项目结构,开发者能够依据实际需求灵活构建应用。
  • 灵活扩展:借助丰富的扩展库,可按需添加诸如数据库支持、身份验证等功能。
  • 适合快速开发:对于初学者而言易于上手,同时也能满足快速原型开发以及中小型 Web 应用的开发需求。

(二)核心依赖库

Flask 的核心功能依赖于两个重要的 Python 库:

  1. Werkzeug:作为 Flask 的底层库,提供了 WSGI 接口、HTTP 请求与响应处理、路由等核心功能,是 Flask 实现 Web 请求处理的基础。
  2. Jinja2:这是一个功能强大的模板引擎,用于动态生成 HTML 页面,能够将 Python 数据与 HTML 模板相结合,实现页面的动态渲染。

二、Flask 的安装与首个应用搭建

(一)安装 Flask

使用 Python 的包管理工具pip进行安装,在命令行中执行以下命令:

pip install flask

安装完成后,可通过创建简单应用来验证是否安装成功。

(二)创建首个 Flask 应用

1. 代码示例
from flask import Flask

# 创建Flask应用实例
app = Flask(__name__)

# 定义路由和视图函数
@app.route('/')
def hello_world():
    return 'Hello, World!'

# 启动应用
if __name__ == '__main__':
    app.run(debug=True)
2. 代码详细解析
  • Flask(__name__):创建 Flask 应用实例,__name__参数用于告知 Flask 当前模块的名称,此参数有助于 Flask 在不同模块间进行配置,例如确定静态文件和模板文件的查找路径。
  • @app.route("/"):这是一个路由装饰器,用于定义路由和视图函数的映射关系。“/” 代表根路径,当用户访问应用的根 URL(如http://127.0.0.1:5000/)时,Flask 会调用与之关联的hello_world()视图函数。
  • return 'Hello, World!':视图函数的作用是处理用户的请求并返回响应。在此例中,返回一个简单的字符串 “Hello, World!”,Flask 会将该字符串作为 HTTP 响应返回给客户端。
  • app.run(debug=True):用于启动 Flask 开发服务器。debug=True表示启用调试模式,在调试模式下,开发过程中应用会自动重载,即在修改代码后无需手动重启服务器,应用会自动更新;同时,当发生错误时,会显示详细的错误信息,便于开发者调试代码。

(三)运行 Flask 应用

  1. 保存代码:将上述代码保存为app.py文件。
  2. 命令行运行:在命令行中切换到保存app.py的目录,执行以下命令启动应用:
python app.py

  1. 访问应用:打开浏览器,在地址栏中输入http://127.0.0.1:5000/,即可看到浏览器页面显示 “Hello, World!”,表明 Flask 应用已成功运行。

三、Flask 路由系统深入解析

(一)路由基本概念

Flask 的核心功能之一是路由系统,它的作用是将用户访问的 URL 与对应的视图函数建立连接。Flask 通过装饰器@app.route()来定义路由,视图函数则负责处理用户的请求并返回相应的响应。

(二)动态路由

1. 基本概念

动态路由允许在 URL 中包含动态参数,通过这些参数可以从 URL 中获取数据,并将其传递给视图函数进行处理。

2. 代码示例
@app.route('/greet/')
def greet(name):
    return f'Hello, {name}!'
3. 代码解析
  • :这是动态路由参数的定义方式,Flask 会从 URL 中提取该部分的值,并将其作为参数传递给视图函数greet。例如,当用户访问/greet/John时,URL 中的 “John” 会被提取出来,赋值给参数name,视图函数返回的响应即为 “Hello, John!”。
4. 动态参数类型指定

在定义动态路由时,还可以指定参数的类型,常见的类型包括:

  • string(默认类型,匹配除斜杠外的任意字符串)
  • int(匹配整数)
  • float(匹配浮点数)
  • path(匹配包含斜杠的字符串)
  • uuid(匹配 UUID 字符串)

示例:

@app.route('/user/')
def get_user(user_id):
    return f'User ID: {user_id}'

当用户访问/user/123时,user_id会被解析为整数 123。

(三)支持多种 HTTP 请求方法

Flask 不仅支持默认的 GET 请求,还支持 POST、PUT、DELETE 等常见的 HTTP 请求方法。可以通过methods参数来指定路由允许的请求方法。

1. 代码示例(仅允许 POST 请求)
@app.route('/submit', methods=['POST'])
def submit():
    return 'Form submitted successfully!'
2. 代码解析
  • methods=["POST"]:明确指定该路由仅允许 POST 请求访问。如果用户通过 GET 等其他请求方法访问该路由,Flask 会返回 405 Method Not Allowed 错误。
3. 处理多种请求方法示例
from flask import request

@app.route('/data', methods=['GET', 'POST'])
def handle_data():
    if request.method == 'GET':
        return 'This is a GET request'
    elif request.method == 'POST':
        return 'This is a POST request'

在视图函数中,通过request.method获取请求方法,从而针对不同的请求方法执行不同的处理逻辑。

四、Jinja2 模板引擎的应用

(一)模板引擎基本作用

Jinja2 模板引擎用于动态生成 HTML 页面,它能够将 HTML 文件与 Python 代码分离,使应用结构更加清晰,便于维护和开发。在 Flask 中,模板文件默认存放在templates文件夹中。

(二)基础模板渲染

1. 模板文件示例(greet.html



    
    Flask Example


    

Hello, {{ name }}!

2. 视图函数代码
from flask import render_template

@app.route('/greet/')
def greet(name):
    return render_template('greet.html', name=name)
3. 代码解析
  • render_template('greet.html', name=name):Flask 会自动从templates文件夹中加载greet.html模板文件,并将视图函数中的name变量传递给模板。在模板中,{{ name }}会被替换为实际传递的值。例如,当用户访问/greet/Alice时,页面会显示 “Hello, Alice!”。

(三)模板继承与块

1. 基础模板(base.html



    
    {% block title %}My Website{% endblock %}


    

Welcome to My Website

{% block content %}{% endblock %}

© 2025 My Website

基础模板定义了页面的通用布局结构,其中使用{% block %}标签定义了可覆盖的块,如title块和content块。

2. 子模板(index.html
{% extends "base.html" %}

{% block title %}Home{% endblock %}

{% block content %}
    

Welcome to the homepage!

{% endblock %}
3. 代码解析
  • {% extends "base.html" %}:表示子模板继承自base.html基础模板。
  • {% block title %}Home{% endblock %}:覆盖基础模板中的title块,将页面标题设置为 “Home”。
  • {% block content %}{% endblock %}:覆盖基础模板中的content块,定义页面的主要内容区域。通过模板继承,可以避免重复编写通用的布局代码,提高开发效率。

五、Flask 表单处理与验证

(一)表单处理扩展库 Flask-WTF

Flask 通常结合 Flask-WTF 扩展来简化表单处理和验证操作。Flask-WTF 提供了表单类,允许在表单类中定义字段和验证规则。

(二)安装 Flask-WTF

在命令行中执行以下命令安装 Flask-WTF:

pip install flask-wtf

(三)创建简单表单示例

1. 代码示例(app.py
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired

app = Flask(__name__)
app.secret_key = 's3cr3t'  # 设置密钥,用于CSRF保护等

class NameForm(FlaskForm):
    name = StringField("Name", validators=[DataRequired()])

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        return f'Hello, {form.name.data}!'
    return render_template('index.html', form=form)

if __name__ == '__main__':
    app.run(debug=True)
2. 代码解析
  • FlaskForm:定义表单类时需继承自FlaskForm类,通过该类可以方便地定义表单字段和验证规则。
  • StringField("Name", validators=[DataRequired()]):定义一个文本输入字段 “Name”,validators=[DataRequired()]表示该字段为必填项,使用DataRequired验证器确保用户提交表单时该字段不为空。
  • form.validate_on_submit():该方法用于检查表单是否通过验证并被提交。在请求为 POST 方法时,会对表单数据进行验证,如果所有必填字段都已填写且符合验证规则,则返回True,否则返回False
3. 模板文件(index.html



    
    Flask Form


    

Enter your name:

{{ form.csrf_token }} {{ form.name() }}

{% if form.name.data %}

Hello, {{ form.name.data }}!

{% endif %}
4. 模板代码解析
  • {{ form.csrf_token }}:Flask-WTF 会自动生成并验证 CSRF(跨站请求伪造)token,该标签用于在表单中插入 CSRF token 字段,以保护应用免受 CSRF 攻击。
  • {{ form.name() }}:通过 Jinja2 模板渲染表单字段name,该标签会自动生成对应的 HTML 输入标签,如
  • {% if form.name.data %}:在模板中通过条件判断,当用户提交了表单且name字段不为空时,显示欢迎信息,其中form.name.data获取表单字段提交的值。

(四)常见表单验证规则

除了DataRequired验证器外,wtforms 还提供了许多其他常用的验证规则,以下是一些示例:

  • Length(min=2, max=50):验证输入的长度,要求输入字符串的长度在指定的最小值和最大值之间。例如:
    email = StringField("Email", validators=[Length(min=6, max=50)])
    
  • Email():验证输入是否是有效的邮箱地址。例如:
    email = StringField("Email", validators=[Email()])
    
  • EqualTo('password'):验证两个字段的值是否相等,通常用于验证确认密码等场景。例如:
    password = PasswordField("Password", validators=[DataRequired()])
    confirm_password = PasswordField("Confirm Password", validators=[DataRequired(), EqualTo('password', message='Passwords must match')])
    

六、Flask 项目结构与部署

(一)典型项目结构

随着 Flask 应用复杂度的增加,合理的项目结构有助于更好地组织代码和资源。一个典型的 Flask 项目结构如下:

/my_flask_app
├── app
│   ├── templates       # 存放所有HTML模板文件
│   │   └── index.html
│   ├── static          # 存放静态文件(如CSS、JS、图片等)
│   │   ├── css
│   │   └── js
│   ├── __init__.py     # 初始化Flask应用
│   ├── routes.py       # 定义所有路由和视图函数
│   └── forms.py        # 定义表单类
└── run.py              # 应用启动文件

(二)Flask 应用部署

在开发环境中,通常使用flask runapp.run()启动应用,但在生产环境中,需要使用更强大、更稳定的 Web 服务器进行部署。以下介绍两种常见的部署方式:

1. 使用 Gunicorn 部署

Gunicorn是一个 Python WSGI HTTP 服务器,常用于生产环境部署 Flask 应用。

(1)安装 Gunicorn

在命令行中执行以下命令安装 Gunicorn:

pip install gunicorn
(2)启动应用

假设 Flask 应用的实例在run.py文件中定义,例如run.py中的代码为:

from app import app

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

则可以通过以下命令启动 Gunicorn 服务器:

gunicorn -w 4 run:app

  • -w 4:指定工作线程数为 4,可根据服务器的性能进行调整。
  • run:apprun是指向 Flask 应用实例的模块名(即run.py文件),app是 Flask 应用实例的名称(在run.py中通过from app import app导入的app)。
2. 结合 Nginx 作为反向代理

Nginx是一款高性能的 Web 服务器和反向代理服务器,在生产环境中,通常将 Nginx 与 Gunicorn 结合使用。Nginx 用于处理静态文件请求,并将动态请求转发给 Gunicorn 服务器处理,这样可以提高应用的性能和稳定性。

(1)安装 Nginx

根据不同的操作系统,使用相应的包管理工具安装 Nginx。例如,在 Ubuntu 系统中,可以执行以下命令安装:

sudo apt-get install nginx
(2)配置 Nginx

假设 Flask 应用通过 Gunicorn 运行在本地的 8000 端口,以下是一个简单的 Nginx 配置示例(配置文件通常位于/etc/nginx/sites-available/目录下):

server {
    listen 80;
    server_name your-domain.com;  # 替换为实际的域名

    location / {
        proxy_pass http://127.0.0.1:8000;  # 将请求转发到Gunicorn服务器
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static/ {
        alias /path/to/your/static/files/;  # 替换为实际的静态文件路径
        autoindex on;
    }
}

配置完成后,需要重启 Nginx 使配置生效:

sudo service nginx restart

七、简单博客应用案例实践

(一)项目结构

/simple_blog
├── app
│   └── templates
│       └── index.html
└── app.py

(二)代码实现

1. app.py代码
from flask import Flask, render_template, request

app = Flask(__name__)
# 使用列表存储所有文章(仅用于演示,实际项目中需使用数据库)
posts = []

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        # 从表单中获取用户提交的标题和内容
        title = request.form['title']
        content = request.form['content']
        # 将文章添加到列表中
        posts.append({'title': title, 'content': content})
    # 渲染模板并传递文章列表
    return render_template('index.html', posts=posts)

if __name__ == '__main__':
    app.run(debug=True)
2. 代码解析
  • 数据存储:通过 Python 列表posts临时存储用户提交的文章,每篇文章以字典形式保存,包含title(标题)和content(内容)两个键值对。这种方式仅适用于演示场景,实际项目中应使用数据库(如 SQLite、MySQL 等)进行持久化存储。
  • 表单提交处理:当用户通过表单提交文章时(request.method == 'POST'),使用request.form获取表单中titlecontent字段的值,然后将新文章添加到posts列表中。
  • 模板渲染:无论用户是首次访问(GET 请求)还是提交表单(POST 请求),都会调用render_template('index.html', posts=posts)渲染模板,并将posts列表传递给模板,以便在页面上展示所有已提交的文章。
3. 模板文件(index.html



    
    Simple Blog


    

Welcome to the Blog!

Submit a Post





Posts:

    {% for post in posts %}
  • {{ post.title }}

    {{ post.content }}

  • {% endfor %}
4. 模板代码解析
  • 表单设计:包含两个必填字段,标题(title)使用单行文本框,内容(content)使用