【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 定义了两个字段:title 和 year。每个字段都带有一些验证规则,例如 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.label 和 form.title() 渲染表单字段和对应的标签。错误消息也会根据表单字段的验证规则自动显示。

7.10 小结

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

进阶提示

  • 表单验证:如果你的应用更复杂,使用 Flask-WTF 可以帮助你自动验证表单数据,避免重复的验证代码。
  • 使用 JavaScript 增强体验:可以在前端使用 JavaScript 验证表单数据并进行动态更新,而不需要每次提交表单后才得到结果。
  • 多文件上传:Flask-WTF 支持文件上传功能,可以方便地处理文件类型的表单字段。
相关推荐
今天早睡4 小时前
用 State、Reducer 和条件边搭出可控循环
后端
站大爷IP4 小时前
Python的字符串格式化把我坑惨了,原来f-string和format的区别这么大
后端
雾行0x004 小时前
精排:推荐系统如何给内容打分?从多目标预估到分数融合
后端·架构
今天早睡4 小时前
Checkpointer 和 thread_id 如何让状态跨调用延续
后端
全栈练习生4 小时前
文档智能与实践
python·ai
用户423341246194 小时前
Redis 缓存穿透、击穿、雪崩,一次性讲清楚
后端
姜鱼问生5 小时前
2G 内存跑 5 个容器频频 OOM?一招 Swap 抢救你的 2核2G 小破服务器
后端
jose5 小时前
存量 Eureka 平滑接入 Nacos:内嵌 Sync 与双注册 SDK 双路线对比
后端·架构
隐擎fox5 小时前
深入 Android 移动端风控与协议层对抗:内核级虚拟环境检测、网络堆栈特征伪装与住宅 IP 协同实战
android·网络·python·网络协议·tcp/ip
“AI国潮设计-小江”5 小时前
【AIGC实战】Python+SDXL批量生成「潮汕英歌舞冰淇淋蛋糕&红桃粿咖啡」IP,固定角色形象批量出甜品商业效果图
开发语言·人工智能·python·prompt·aigc