Flask-Form表单的使用及其csrf_token的开启使用(六)

Django 当中有form类,这个类给开发者提供了相当丰富的校验方式。
Flask和django同样推出了form类的插件,flask-wtf

一、flask form表单的安装和简单字段属性的应用

1、安装flask form插件

pip install flask-wtf

在这里插入图片描述
在这里插入图片描述

2、flask项目主目录下创建forms.py文件
在这里插入图片描述

3、表单常用的字段

字段说明
StringField字符串
IntegerField整型
TextAreaField文本
PasswordField密码
HiddenField隐藏域
DateFieldDatatime.data格式 年月日
DateTimeFieldDatatime.datatime 格式 年月日 时分秒
FloatField小数
RadioField单选
SelectField下拉
FileField文件
SubmitField提交

表单常用的校验

校验参数说明
Email邮件校验
EqualTo比较两个字段的值,常用于密码比较
IPAddressIpv4格式的IP地址
Length长度
NumberRange数字范围
DataRequired空值检查
Url验证是否符合url格式
AnyOf确保输入值在指定范围
NoneOf确保输入的值不在范围

4、在forms.py文件中导入form表单相关模块,并定义一个Form类

import wtforms # 定义字段
from flask_wtf import FlaskForm # 定义表单
from wtforms import validators # 定义校验
from FlaskStudent.models import Course

course_list = [(c.id,c.name) for c in Course.query.all()]

class TeacherForm(FlaskForm):
    """
    form字段的参数
    label=None, 表单的标签
    validators=None, 校验,传入校验的方法
    filters=tuple(), 过滤
    description='',  描述
    id=None, html id
    default=None, 默认值
    widget=None, HTML样式
    render_kw=None, HTML属性 参数
    """

    name = wtforms.StringField(
        label="教师姓名",
        render_kw={
            "class": "form-control",
            "placeholder": "教师姓名"
        },
        validators=[
            validators.DataRequired("姓名不可以为空")
        ]
    )
    age = wtforms.IntegerField(
        label="教师年龄",
        render_kw={
            "class": "form-control",
            "placeholder": "教师年龄"
        },
        validators=[
            validators.DataRequired("年龄不可以为空")
        ]
    )
    gender = wtforms.SelectField(
        label="教师性别",
        render_kw={
            "class": "form-control",
        },
        choices=[
            ("1","男"),
            ("2","女")
        ]
    )
    course = wtforms.SelectField(
        label="学科",
        render_kw={
            "class": "form-control",
        },
        choices=course_list
    )
    submit = wtforms.SubmitField(
        label="提交",
        render_kw={
            "class": "btn btn-primary btn-block",
        },
    )

5、视图路由文件中定义一个视图函数,并实例化表单,用于前端渲染

@app.route("/add_teacher/",methods=["GET","POST"])
def add_teacher():
    teacher_form = TeacherForm()
    return render_template("add_teacher.html",**locals())

6、前端页面,使用变量渲染form类中的字段
在这里插入图片描述
7、页面效果
在这里插入图片描述

二、flask form 中csrf_token 的使用

flask-wtf模块是携带csrf校验的,只是需要开启。在flask form中默认csrf_token 是没有开启的,需要我们手动去启动form表单的csrf_token。

csrf是针对于post请求的跨域限制,对get请求是没有作用的。

1、首先更改form表单的请求方式为post
在这里插入图片描述

2、首先在项目起始位置开启CSRFProtect,也就是main.py

这里注意由于版本问题,现在可以使用csrfProtect,之前版本会更新到CSRFProtect,所以我们现在索性就直接使用CSRFProtect,避免之后出现问题

导入CSRFProtect模块,关联flask应用
在这里插入图片描述

import pymysql
from flask import Flask
from flask import session
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import CSRFProtect # 导入csrf校验模块,csrfProtect在1.0之后移除

pymysql.install_as_MySQLdb()

app = Flask(__name__)

# 关联csrf和flask应用
csrf = CSRFProtect(app)
# 使用类配置加载
app.config.from_object('config.DebugConfig')


# 关联sqlalchemy和flask应用
db = SQLAlchemy(app)

3、然后在前端使用csrf_token就可以了

这里是根据form表单实例去使用csrf_token的

在这里插入图片描述

如果不配置这句话,而程序入口已经开启了应用的CSRF校验,则会在表单提交时报错

在这里插入图片描述

4、前端页面上打开开发者调试模式,查看csrf_token是否已经生成在隐藏域中
在这里插入图片描述

这里注意:

Django中的csrf_token的name名为middlewarecsrftoken
Flask中的csrf_token的name名为csrf_token

三、临时关闭csrf校验

有时候我们有一些功能虽然用的是post请求,但是又不想进行csrf校验,同时其他的一些功能视图还是需要用csrf校验的,这个时候就需要用到csrf内置的功能,临时关闭保护。

针对于指定的单个视图取消csrf的保护

在不需要保护的路由上方加上这句话:
@csrf.exempt

前提是开启CSRF时需要将CSRFProtect使用一个csrf变量实例化

在这里插入图片描述

然后在视图中导入main.py中应用的csrf对象
在这里插入图片描述

最后在不需要保护的视图路由上方加上这句话

这个时候哪怕是程序入口开启了csrf,还有前端页面页使用了表单实例的csrf_token,但是这时候是不会进行csrf的校验的
在这里插入图片描述

from flask import request
from flask import redirect

from flask import render_template
from FlaskStudent.main import app
from FlaskStudent.models import *
from FlaskStudent.main import csrf
from FlaskStudent.main import session
from FlaskStudent.forms import TeacherForm

@csrf.exempt # 临时关闭csrf校验
@app.route("/add_teacher/",methods=["GET","POST"])
def add_teacher():
    teacher_form = TeacherForm()
    return render_template("add_teacher.html",**locals())

四、定义csrf错误页面

就是在form表单提交,csrf校验失败(不通过)的情况下,不进行下面的报错
在这里插入图片描述

而是跳转到指定的错误提示页面。

这里我们需要新建一个错误提示页面:命名为csrf_403.html

{% extends "blank.html" %}

{% block label %}
    403 error
{% endblock %}

{% block container %}
    <div class="text-center">
        <div class="error mx-auto" data-text="403">403</div>
        <p class="lead text-gray-800 mb-5">csrf_token error</p>
        <p class="text-gray-500 mb-0">please check your settings or form,csrf_token is missing ! </p>
    </div>
{% endblock %}

再定义一个csrf_403的路由视图,用于发生校验错误跳转
这里必须传递一个参数reason,也不需要使用它或是返回它。如果不传递,csrf内置代码就识别不了,会报错。

# csrf 如果没有配置跳转的错误页面
# @csrf.error_handler
@app.route("/csrf_403/")
def csrf_tonken_error(reason):
    return render_template("csrf_403.html")

视图路由定义完了,再跟关闭csrf保护一样,在路由上方添加一个装饰器

@csrf.error_handler

添加这句话之后,只要前端提交表单时csrf校验失败,就是跳转到该路由视图指定的页面(该方法使用于所有csrf校验失败的视图)

from flask import request
from flask import redirect

from flask import render_template
from FlaskStudent.main import app
from FlaskStudent.models import *
from FlaskStudent.main import csrf
from FlaskStudent.main import session
from FlaskStudent.forms import TeacherForm

@csrf.exempt # 临时关闭csrf校验
@app.route("/add_teacher/",methods=["GET","POST"])
def add_teacher():
    teacher_form = TeacherForm()
    return render_template("add_teacher.html",**locals())

# csrf 如果没有配置跳转的错误页面
@csrf.error_handler # csrf错误跳转
@app.route("/csrf_403/")
def csrf_tonken_error(reason):
    return render_template("csrf_403.html")

效果:

我现在将add_teacher.html页面上的csrf变量注释掉

在这里插入图片描述
这个时候提交表单

在这里插入图片描述

就会跳转的定义的403页面

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孜孜孜孜不倦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值