【11天从零基础入门flask】第 7 章 表单

第 7 章 表单

Cross-Site Request Forgery(CSRF)是指恶意网站通过伪造用户请求来执行不当操作,像是删除数据或执行其他修改操作。在我们的删除条目操作中,虽然使用了 POST 请求来避免使用 GET 请求执行敏感操作,但这个方法并不安全,因为一个恶意站点仍然可以模拟 POST 请求。因此,推荐使用 CSRF 防护机制。

如何在 Flask 中启用 CSRF 防护

Flask-WTF 提供了 CSRF 保护,可以自动生成 CSRF 令牌,并验证该令牌,以确保请求来源是合法的。要启用 CSRF 防护,你需要安装 Flask-WTF:

bash 复制代码
pip install Flask-WTF

然后在 app.py 中启用 CSRF 防护:

python 复制代码
from flask_wtf.csrf import CSRFProtect

# 实例化 CSRF 防护
csrf = CSRFProtect(app)

# 确保所有 POST 请求都需要 CSRF 验证

Flask-WTF 会在每个 POST 请求中自动验证请求中的 CSRF 令牌。通过这种方法,我们可以确保提交的表单仅来自我们的应用,而不是恶意网站。

7.9 使用 Flask-WTF 简化表单处理

虽然我们已经通过手动处理表单数据来实现了表单提交的功能,但当应用变得更复杂时,手动管理表单数据和验证可能会变得冗长且易出错。在这种情况下,使用 Flask-WTF 可以帮助我们简化表单管理和验证。

1. 安装 Flask-WTF

首先,安装 Flask-WTF 扩展:

bash 复制代码
pip install flask-wtf
2. 创建一个表单类

Flask-WTF 让你能够通过创建 Python 类来定义表单,表单中的每个字段都被定义为类的属性。以下是一个简单的表单类:

python 复制代码
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired, Length

class MovieForm(FlaskForm):
    title = StringField('Title', validators=[DataRequired(), Length(max=60)])
    year = StringField('Year', validators=[DataRequired(), Length(min=4, max=4)])

在这个类中,MovieForm 定义了两个字段:titleyear。每个字段都带有一些验证规则,例如 DataRequired 确保该字段不为空,Length 确保字段长度符合要求。

3. 在视图中使用表单

在视图函数中,我们将 Flask-WTF 表单类作为实例传入模板。示例如下:

python 复制代码
from flask import render_template, redirect, url_for, flash
from app import app, db
from .forms import MovieForm
from .models import Movie

@app.route('/', methods=['GET', 'POST'])
def index():
    form = MovieForm()

    if form.validate_on_submit():
        title = form.title.data
        year = form.year.data

        movie = Movie(title=title, year=year)
        db.session.add(movie)
        db.session.commit()

        flash('Item created.')
        return redirect(url_for('index'))

    movies = Movie.query.all()
    return render_template('index.html', form=form, movies=movies)

在这里,我们实例化了一个 MovieForm 对象 form,并通过 form.validate_on_submit() 来检查表单是否有效。如果表单提交且验证通过,数据将会被存储到数据库中。

4. 在模板中渲染表单

Flask-WTF 提供了一个方便的 form 对象,用来在模板中渲染表单。你可以像这样在 index.html 中渲染表单:

html 复制代码
<form method="post">
    {{ form.hidden_tag() }}  <!-- 隐藏 CSRF 令牌 -->
    <div>
        {{ form.title.label }} {{ form.title() }}
        {% for error in form.title.errors %}
            <div class="error">{{ error }}</div>
        {% endfor %}
    </div>
    <div>
        {{ form.year.label }} {{ form.year() }}
        {% for error in form.year.errors %}
            <div class="error">{{ error }}</div>
        {% endfor %}
    </div>
    <input class="btn" type="submit" value="Add">
</form>

在模板中,我们使用 form.hidden_tag() 渲染隐藏的 CSRF 令牌。然后,通过 form.title.labelform.title() 渲染表单字段和对应的标签。错误消息也会根据表单字段的验证规则自动显示。

7.10 小结

在本章中,我们学习了如何通过 Flask 表单处理数据,包括创建、编辑和删除条目。我们掌握了如何从模板收集用户输入的数据,如何在视图中处理这些数据,并进行必要的验证。通过 Flask-WTF 扩展,我们能够简化表单的创建、验证和渲染,并实现 CSRF 防护。

进阶提示

  • 表单验证:如果你的应用更复杂,使用 Flask-WTF 可以帮助你自动验证表单数据,避免重复的验证代码。
  • 使用 JavaScript 增强体验:可以在前端使用 JavaScript 验证表单数据并进行动态更新,而不需要每次提交表单后才得到结果。
  • 多文件上传:Flask-WTF 支持文件上传功能,可以方便地处理文件类型的表单字段。
相关推荐
Mr.Entropy5 分钟前
JdbcTemplate 性能好,但 Hibernate 生产力高。 如何选择?
java·后端·hibernate
亮子AI19 分钟前
【Python】比较两个cli库:Click vs Typer
开发语言·python
YDS82920 分钟前
SpringCloud —— MQ的可靠性保障和延迟消息
后端·spring·spring cloud·rabbitmq
CappuccinoRose26 分钟前
流计算概述
python·flink·流计算·数据流·pyflink
Dragon水魅26 分钟前
Fandom Wiki 网站爬取文本信息踩坑实录
爬虫·python
Darkershadow30 分钟前
蓝牙学习之unprovision beacon
python·学习·ble
无限大642 分钟前
为什么"区块链"不只是比特币?——从加密货币到分布式应用
后端
洛神么么哒1 小时前
freeswitch-初级-01-日志分割
后端
蝎子莱莱爱打怪1 小时前
我的2025年年终总结
java·后端·面试
小龙在山东1 小时前
基于 plumbum 跨平台执行Shell脚本
python