在视图函数中验证表单

因为现在的basic_form视图同时接受两种类型的请求:GET请求和POST请求。所以我们要根据请求方法的不同执行不同的代码。具体来说,首先是实例化表单,如果是GET请求,就渲染模板;如果是POST请求,就调用validate()方法验证表单数据。

请求的HTTP方法可以通过requeset.method属性获取,我们可以使用下面的方式来组织视图函数:

from flask import request

@app.route('/basic', methods=['GET','POST'])
def basic():
form = LoginForm() #GET + POST
#如果用户提交表单,并且数据通过验证
if request.method == 'POST' and form.validate():
#获取表单数据并保存
...#处理POST请求
return render_template('forms/basic.html',form=form) #处理GET请求

当请求方法是GET时,会跳过这个if语句,渲染basic.html模板;当请求的方法是POST时(说明用户提交了表单),则验证表单数据。这会逐个字段(包括CSRF令牌字段)调用附加的验证器进行验证。

因为WTForms会自动对CSRF令牌字段进行验证,如果没有渲染该字段会导致验证出错,错误消息为”CSRF token is missing”。

Flask-WTF提供的validate_on_submit()方法合并了这两个操作(判断请求方法和验证表单字段),因此上面的代码可以简化为:

@app.route('/basic', methods=['GET','POST'])
def basic():
form = LoginForm()
if form.validate_on_submit():
...
return render_template('basic.html', form=form)

除了POST方法,如果请求的方法是PUT、PATCH和DELETE方法,form.validate_on_submit()也会验证表单数据。

如果form.validate_on_submit()返回True,则表示用户提交了表单,且表单通过验证,那么我们就可以在这个if语句内获取表单数据,比如:

from flask import Flask, render_template, redirect, url_for, flash

@app.route('/basic', methods=['GET', 'POST'])
def basic():
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
flash('Welcom home, %s!' % username)
return redirect(url_for('hello'))
return render_template('basic.html', form = form) @app.route('/hello')
def hello():
return render_template('hello.html')
表单类的data属性是一个匹配所有字段与对应数据的字典,我们一般直接通过”form.字段属性名.data”的形式来获取对应字段的数据。例如,form.username.data返回username字段的值。在代码中,当表单验证成功后,我们获取了username字段的数据,然后用来发送一条flash消息,最后将程序重定向到hello视图。
表单的数据一般会存储到数据库中,在这里将数据填充到flash()函数里。
先访问127.0.0.1:5000/basic


输入表单内容,点击提交,触发validate_on_submit()方法
发送闪现消息
闪现消息在重定向后的hello页面显示


程序的逻辑是:访问/basic页面,提交了表单后,触发了视图函数里的表单验证逻辑,之后flash了消息,然后重定向到hello视图(页面重定向到/hello地址),在hello页面显示了flash消息
 
在basic模板中定义了表单,继承了base模板:
basic.html:
{% extends 'base.html' %}
{% block content %}
<form method="post">
{{ form.csrf_token }}<!-- 渲染CSRF令牌隐藏字段 -->
{{ form.username.label }}{{ form.username }}<br>
{{ form.password.label }}{{ form.password }}<br>
{{ form.remember }}{{ form.remember.label }}<br>
{{ form.submit }}<br>
</form>
{% endblock %}
同时hello.html模板也继承了basic模板,在basic模板中有get_flashed_messages()方法来处理flash消息,使得basic视图的flash消息能够在重定向到hello.html模板时可以在页面显示
base.html模板:
 
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
{% block metas %}
<meta charset="utf-8">
{% endblock metas %}
<title>
{% block title %}
Form - HelloFlask
{% endblock title %}
</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='favicon.ico') }}">
{% block styles %}
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
{% endblock styles %}
{% endblock head %}
</head>
<body>
<nav>
{% block nav %}
<ul>
<li><a href="{{ url_for('basic') }}">Home</a></li>
</ul>
{% endblock %}
</nav> <main>
{% for message in get_flashed_messages() %}
<div class="alert">
{{ message }}
</div>
{% endfor %}
{% block content %}{% endblock %}
</main>
<footer>
{% block footer %}
<small> &copy; 2019 <a href="https://www.cnblogs.com/xiaxiaoxu/" title="xiaxiaoxu's blog">夏晓旭的博客</a> /
<a href="https://github.com/xiaxiaoxu/hybridDrivenTestFramework" title="Contact me on GitHub">GitHub</a> /
<a href="http://helloflask.com" title="A HelloFlask project">Learning from GreyLi's HelloFlask</a>
</small>
{% endblock %}
</footer>
{% block scripts %}{% endblock %}
</body>
</html>
hello.html模板:
 
{% extends 'base.html' %}
{% block content %}
<title>Hello from Flask</title>
<ul>
<li><a href="{{ url_for('hello') }}">xiaxiaoxu</a></li>
</ul>
{% endblock %}

flask 在视图函数中验证表单的更多相关文章

  1. Flask从入门到精通之在视图函数中处理表单

    在新版hello.py 中,视图函数index() 不仅要渲染表单,还要接收表单中的数据.更新后的index() 视图函数如下: @app.route('/') def index(): name = ...

  2. 在springboot中验证表单信息(六)

    构建工程 创建一个springboot工程,由于用到了 web .thymeleaf.validator.el,引入相应的起步依赖和依赖,代码清单如下: 1 2 3 4 5 6 7 8 9 10 11 ...

  3. Spring Boot教程(六)在springboot中验证表单信息

    构建工程 创建一个springboot工程,由于用到了 web .thymeleaf.validator.el,引入相应的起步依赖和依赖,代码清单如下: <dependencies> &l ...

  4. flask中的表单文件上传

    在表单中上传文件时,一定要加入 enctype="multipart/form-data" 属性 为什么要加入这个属性呢: enctype就是encodetype就是编码类型的意思 ...

  5. flask 在模板中渲染表单

    在模板中渲染表单 为了能够在模板中渲染表单,我们需要把表单类实例传入模板.首先在视图函数里实例化表单类LoginForm,然后再render_template()函数中使用关键脑子参数form将表单实 ...

  6. SpringBoot非官方教程 | 第十九篇: 验证表单信息

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot19/ 本文出自方志朋的博客 这篇文篇主要简述如何 ...

  7. ValidForm验证表单

    在做项目时,要求熟悉项目中验证表单的插件,所以学习一下validForm这个插件 http://validform.rjboy.cn/document.html#validformObject

  8. AngularJS中的表单验证

    AngularJS中的表单验证 AngularJS自带了很多验证,什么必填,最大长度,最小长度...,这里记录几个有用的正则式验证 1.使用angularjs的表单验证 正则式验证 只需要配置一个正则 ...

  9. angular中的表单验证

    angular中的表单验证很强大, 一共有5中验证信息,$valid,$invalid,$pristine,$dirty,$error. $valid-----当验证通过的时候,为true,不通过的时 ...

随机推荐

  1. GPT转MBR怎么转?

    GPT转MBR分区怎么转?现在很多笔记本的硬盘分区都是GPT模式,如果想装XP的话,那只能将GPT磁盘转换成MBR磁盘分区才行.接下来,简单说说如何将GPT分区转成MBR分区! 如果本身电脑有两个硬盘 ...

  2. 晨枫U盘启动盘制作工具V4.0-安装原版XP的方法

    [1]进入第一个PE后找到我们事先准备好的xp光盘iso镜像,右键点击加载虚拟磁盘(也可以利用虚拟光驱来加载或者直接用右键里的RAR解压到本地硬盘分区) [2]打开桌面上的windows安装工具,wi ...

  3. Spark中的partition和block的关系

    hdfs中的block是分布式存储的最小单元,类似于盛放文件的盒子,一个文件可能要占多个盒子,但一个盒子里的内容只可能来自同一份文件.假设block设置为128M,你的文件是250M,那么这份文件占3 ...

  4. [js]js的表单验证onsubmit方法

    http://uule.iteye.com/blog/2183622 表单验证类 <form class="form" method="post" id= ...

  5. api-gateway-engine知识点(1)

    1     密钥绑定时,通过Channel 实现监控 后台发送数据 :      redisTemplate.convertAndSend(RedisMessageChannel.API_GATEWA ...

  6. Linux开启root用户

    1.进入系统的时候Ctrl + Alt + F1,切换到命令窗口,登录现有用户: 2.执行sudo passwd root + root的密码: 3.按照要求输入密码: ==> root用户密码 ...

  7. DLNg序列模型第二周NLP与词嵌入

    1.使用词嵌入 给了一个命名实体识别的例子,如果两句分别是“orange farmer”和“apple farmer”,由于两种都是比较常见的,那么可以判断主语为人名. 但是如果是榴莲种植员可能就无法 ...

  8. 2018-2019-1 20189221 《Linux内核原理与分析》第八周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第八周作业 实验七 编译链接过程 gcc –e –o hello.cpp hello.c / gcc -x cpp-o ...

  9. PHP Fatal error: Uncaught ErrorException: preg_match_all (): JIT compilation failed: no more memory in phar

    PHP 升级到 7.3 后,出现 BUG: 解决办法:修改php.ini文件,;pcre.jit=1 =>  pcre.jit=0

  10. 23-Python3 File

    ''' file(文件)方法 ''' #open()对象 pass #file对象 ##file.close():关闭文件,关闭后不能再进行读写操作 fo1 = open('/Users/ligaij ...