Flask 【第七篇】Flask中的wtforms使用

一、简单介绍flask中的wtforms

WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。

安装:

pip3 install wtforms

二、简单使用wtforms组件

1、用户登录

具体代码:

from  flask import Flask,render_template,request,redirect
from  wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import Form
from wtforms import validators
from wtforms import widgets
app = Flask(__name__,template_folder="templates")class Myvalidators(object):'''自定义验证规则'''def __init__(self,message):self.message = messagedef __call__(self, form, field):print(field.data,"用户输入的信息")if field.data == "haiyan":return Noneraise validators.ValidationError(self.message)class LoginForm(Form):'''Form'''name = simple.StringField(label="用户名",widget=widgets.TextInput(),validators=[Myvalidators(message="用户名必须是haiyan"),#也可以自定义正则validators.DataRequired(message="用户名不能为空"),validators.Length(max=8,min=3,message="用户名长度必须大于%(max)d且小于%(min)d")],render_kw={"class":"form-control"}  #设置属性)pwd = simple.PasswordField(label="密码",validators=[validators.DataRequired(message="密码不能为空"),validators.Length(max=8,min=3,message="密码长度必须大于%(max)d且小于%(min)d"),validators.Regexp(regex="\d+",message="密码必须是数字"),],widget=widgets.PasswordInput(),render_kw={"class":"form-control"})@app.route('/login',methods=["GET","POST"])
def login():if request.method =="GET":form = LoginForm()return render_template("login.html",form=form)else:form = LoginForm(formdata=request.form)if form.validate():print("用户提交的数据用过格式验证,值为:%s"%form.data)return "登录成功"else:print(form.errors,"错误信息")return render_template("login.html",form=form)if __name__ == '__main__':# app.__call__()app.run(debug=True)

login.html

<body>
<form action="" method="post" novalidate><p>{{ form.name.label }} {{ form.name }} {{ form.name.errors.0 }}</p><p>{{ form.pwd.label }} {{ form.pwd }} {{ form.pwd.errors.0 }}</p><input type="submit" value="提交"><!--用户名:<input type="text">--><!--密码:<input type="password">--><!--<input type="submit" value="提交">-->
</form>
</body>

2、用户注册

from flask import Flask,render_template,redirect,request
from wtforms import Form
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgetsapp = Flask(__name__,template_folder="templates")
app.debug = True

=======================simple=========================== class RegisterForm(Form):name = simple.StringField(label="用户名",validators=[validators.DataRequired()],widget=widgets.TextInput(),render_kw={"class":"form-control"},default="haiyan")pwd = simple.PasswordField(label="密码",validators=[validators.DataRequired(message="密码不能为空")])pwd_confim = simple.PasswordField(label="重复密码",validators=[validators.DataRequired(message='重复密码不能为空.'),validators.EqualTo('pwd',message="两次密码不一致")],widget=widgets.PasswordInput(),render_kw={'class': 'form-control'})

  ========================html5============================email = html5.EmailField( #注意这里用的是html5.EmailFieldlabel='邮箱',validators=[validators.DataRequired(message='邮箱不能为空.'),validators.Email(message='邮箱格式错误')],widget=widgets.TextInput(input_type='email'),render_kw={'class': 'form-control'})

  ===================以下是用core来调用的=======================gender = core.RadioField(label="性别",choices=((1,"男"),(1,"女"),),coerce=int #限制是int类型的)city = core.SelectField(label="城市",choices=(("bj","北京"),("sh","上海"),))hobby = core.SelectMultipleField(label='爱好',choices=((1, '篮球'),(2, '足球'),),coerce=int)favor = core.SelectMultipleField(label="喜好",choices=((1, '篮球'),(2, '足球'),),widget = widgets.ListWidget(prefix_label=False),option_widget = widgets.CheckboxInput(),coerce = int,default = [1, 2])def __init__(self,*args,**kwargs): #这里的self是一个RegisterForm对象'''重写__init__方法'''super(RegisterForm,self).__init__(*args, **kwargs) #继承父类的init方法self.favor.choices =((1, '篮球'), (2, '足球'), (3, '羽毛球')) #吧RegisterForm这个类里面的favor重新赋值def validate_pwd_confim(self,field,):'''自定义pwd_config字段规则,例:与pwd字段是否一致:param field::return:'''# 最开始初始化时,self.data中已经有所有的值if field.data != self.data['pwd']:# raise validators.ValidationError("密码不一致") # 继续后续验证raise validators.StopValidation("密码不一致") # 不再继续后续验证@app.route('/register',methods=["GET","POST"]) def register():if request.method=="GET":form = RegisterForm(data={'gender': 1}) #默认是1,return render_template("register.html",form=form)else:form = RegisterForm(formdata=request.form)if form.validate(): #判断是否验证成功print('用户提交数据通过格式验证,提交的值为:', form.data) #所有的正确信息else:print(form.errors) #所有的错误信息return render_template('register.html', form=form)if __name__ == '__main__':app.run()

register.html

<body>
<h1>用户注册</h1>
<form method="post" novalidate style="padding:0  50px">{% for item in form %}<p>{{item.label}}: {{item}} {{item.errors[0] }}</p>{% endfor %}<input type="submit" value="提交">
</form>
</body>

 3、meta

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Flask, render_template, request, redirect, session
from wtforms import Form
from wtforms.csrf.core import CSRF
from wtforms.fields import core
from wtforms.fields import html5
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets
from hashlib import md5app = Flask(__name__, template_folder='templates')
app.debug = Trueclass MyCSRF(CSRF):"""Generate a CSRF token based on the user's IP. I am probably not verysecure, so don't use me."""def setup_form(self, form):self.csrf_context = form.meta.csrf_context()self.csrf_secret = form.meta.csrf_secretreturn super(MyCSRF, self).setup_form(form)def generate_csrf_token(self, csrf_token):gid = self.csrf_secret + self.csrf_contexttoken = md5(gid.encode('utf-8')).hexdigest()return tokendef validate_csrf_token(self, form, field):print(field.data, field.current_token)if field.data != field.current_token:raise ValueError('Invalid CSRF')class TestForm(Form):name = html5.EmailField(label='用户名')pwd = simple.StringField(label='密码')class Meta:# -- CSRF# 是否自动生成CSRF标签csrf = True# 生成CSRF标签namecsrf_field_name = 'csrf_token'# 自动生成标签的值,加密用的csrf_secretcsrf_secret = 'xxxxxx'# 自动生成标签的值,加密用的csrf_contextcsrf_context = lambda x: request.url# 生成和比较csrf标签csrf_class = MyCSRF# -- i18n# 是否支持本地化# locales = Falselocales = ('zh', 'en')# 是否对本地化进行缓存cache_translations = True# 保存本地化缓存信息的字段translations_cache = {}@app.route('/index/', methods=['GET', 'POST'])
def index():if request.method == 'GET':form = TestForm()else:form = TestForm(formdata=request.form)if form.validate():print(form)return render_template('index.html', form=form)if __name__ == '__main__':app.run()

 

 

转载于:https://www.cnblogs.com/xiaohema/p/8456741.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281195.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS自定义滚动条样式

css通过滚动条伪类来修改滚动条样式&#xff0c;伪类名称如下 ::-webkit-scrollbar 滚动条整体部分 ::-webkit-scrollbar-track 滚动条轨道&#xff08;里面装有滑块 thumb&#xff09; ::-webkit-scrollbar-thumb 滚动条滑块 ::-webkit-scrollbar-button 滚动条轨道两端按钮 …

为了避免内存攻击,美国国家安全局提倡Rust、C#、Go、Java、Ruby 和 Swift,但将 C 和 C++ 置于一边...

本文翻译自两篇文章&#xff0c;第一篇是对美国国家安全局在“软件内存安全”网络安全信息表的解读&#xff0c;第二篇是普及什么是内存安全&#xff0c;为什么它很重要&#xff1f;第一篇 为了避免内存攻击&#xff0c;美国国家安全局提倡Rust、C#、Go、Java、Ruby 和 Swift&a…

自学python(一)

一、入门仪式 学习一门新语言必不可少的一件事&#xff1a; print("Hello world!")二、基础知识 1、注释&#xff1a; 单行注释&#xff1a; 1 print("Hello world!") #输出Hello world! 多行注释&#xff1a; 这是多行注释 这是多行注释 这是多行注释…

.NET周报【11月第2期 2022-11-15】

国内文章统一的开发平台.NET 7正式发布https://www.cnblogs.com/shanyou/archive/2022/11/09/16871945.html在 2020 年规划的.NET 5功能终于在.NET 7 完成了&#xff0c;为微软和社区一起为多年来将不同的开发产品统一起来的努力加冕&#xff0c;未来只有一个.NET, 回顾.NET 20…

如何像使用AspNetCore中的Controllers 和 Actions一样处理MQTT消息

在物联网项目中&#xff0c; 处理MQTT的topic时费工费力&#xff0c; 代码一团乱&#xff0c; 什么才是最好的姿势&#xff1f;这里面我们极力介绍 MQTTnet.AspNetCore.Routing 项目&#xff0c;MQTTnet AspNetCore Routing 是https://github.com/Atlas-LiftTech/MQTTnet.AspN…

chrome 悬停大图插件_Google Chrome浏览器的悬停卡:我不想要的我最喜欢的新东西

chrome 悬停大图插件If you only have a handful of open tabs in Google Chrome, it’s easy to tell what they are. But as you start to collect more tabs (or make the window smaller), it gets harder. That’s where Hover Cards come in. 如果您在Google Chrome浏览器…

GitHub Codespaces 安装 .NET 7

本文主要介绍如何在 GitHub Codespaces 这个云上 IDE 环境中安装 .NET 7背景GitHub 的 Codespaces 可以让我们随时随地编写代码&#xff0c;一些简单的修改也非常方便快捷。特别是 .NET 7 发布后&#xff0c;一些可以直接升级的小项目只需要更改配置就可以了&#xff0c;我们可…

chrome怎么隐藏浏览器_如何使用Google Chrome的隐藏阅读器模式

chrome怎么隐藏浏览器Chrome 75 has a hidden “Reader” mode that strips web pages down to the bare minimum to make them easier to, well, read. But it’s not enabled by default—here’s how to get it now. Chrome 75具有隐藏的“阅读器”模式&#xff0c;可将网页…

angularjs中使用swiper时不起作用,最后出现空白位

controller.js中定义swipers指令&#xff1a; var moduleCtrl angular.module(newscontroller,[infinite-scroll,ngTouch,news.service]) .directive(swipers,swipers); swipers.$inject [$timeout]; function swipers($timeout) {return {restrict: "EA",scope: {…

使用Jupyter记事本记录和制作.NET可视化笔记

前言&#xff1a;对于记录笔记的工具特别多&#xff0c;不过对于程序员来说&#xff0c;记录笔记程序代码运行结果演示可以同时存在&#xff0c;无疑会极大增加我们的笔记的可读性和体验感。以前在写python的时候&#xff0c;使用jupyter的体验很好&#xff0c;所以此处做一个基…

火狐上如何使用谷歌翻译插件_将Google翻译功能添加到Firefox

火狐上如何使用谷歌翻译插件Are you looking for a quick no-fuss way to translate webpages? Then you will want to take a good look at the Translate extension for Firefox. 您是否正在寻找一种快速简便的方法来翻译网页&#xff1f; 然后&#xff0c;您将需要很好地了…

Android 4.X 系统加载 so 失败的原因分析

1 so 加载过程 so 加载的过程可以参考小米的系统工程师的文章loadLibrary动态库加载过程分析 2 问题分析 2.1 问题 年前项目里新加了一个 so库&#xff0c;但发现native 方法的找不到的 crash 好多&#xff0c;好些都是报了java.lang.unsatisfiedlinkerror native method not f…

桌面显示激活windows_愚蠢的怪胎技巧:如何在桌面上显示Windows版本

桌面显示激活windowsHave you ever noticed during all the beta releases of Windows, there’s always a Windows version on the desktop in the lower right-hand corner? Here’s how that “feature” is enabled or disabled. 您是否曾经在Windows的所有beta版本中都注…

服务网格:限流保护 (上)

背景限流是服务治理中保护服务的重要手段之一&#xff0c;也是最直接有效的手段&#xff0c;它可以保护服务不被瞬间的大流量冲垮&#xff0c;类似电路中的“保险丝”。在服务上线前&#xff0c;我们都会对服务进行基准测试&#xff0c;来了解可通过的最大“电流”。上面所说的…

博弈论进阶之Anti-SG游戏与SJ定理

前言 在上一节中&#xff0c;我们初步了解了一下SG函数与SG定理。 今天我们来分析一下SG游戏的变式——Anti-SG游戏以及它所对应的SG定理 首先从最基本的Anti-Nim游戏开始 Anti-Nim游戏是这样的 有两个顶尖聪明的人在玩游戏&#xff0c;游戏规则是这样的&#xff1a; 有\(n\)堆…

怎样取消outlook约会_快速提示:在Outlook 2010中设置和取消约会

怎样取消outlook约会Getting everyone in one place at the same time for appointments can be daunting at times. Outlook makes it easy to setup appointments and invite attendees as well, and here we look at doing it in Outlook 2010. 同时让每个人都集中在一个地方…

重视和解决 ABP 分布式事件乱序问题

ABP Framework 5.0 实现了单体应用场景下&#xff0c;收件箱和发件箱的事件严格顺序性。但在微服务或多数据库场景下&#xff0c;由于网络时延和设施效率的限制&#xff0c; 分布式事件将不再是 Linearizability [1] 的&#xff0c;因此必然会存在物理时间上的收件乱序。借用 D…

个人博客建站方案推荐

1.服务器选择 正值双十一来临之际各大服务器提供商又大量的优惠活动&#xff0c;各位要步入个人站长行列的小哥们时机要把握好了&#xff0c;我个人使用过阿里云的服务器&#xff0c;腾讯云的服务器&#xff0c;华为云的服务器。其实&#xff0c;个人感觉就放个博客&#xff0c…

linux系统下nginx安装目录和nginx.conf配置文件目录

linux系统下nginx安装目录和nginx.conf配置文件目录 1、查看nginx安装目录 输入命令 # ps -ef | grep nginx 返回结果包含安装目录 root 2662 1 0 07:12 ? 00:00:00 nginx: master process /usr/sbin/nginx 2、查看nginx.conf配置文件目录 输入命令 # nginx…

android启用hdcp_如何在Android上启用优先收件箱(和设置仅重要通知)

android启用hdcpYesterday Google released an updated Gmail application for Android 2.2 phones that supports the Priority Inbox feature—and more importantly, allows you to change your notifications to only alert you for important email. Let’s take a look. …