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 = message
def __call__(self, form, field):
print(field.data,"用户输入的信息")
if field.data == "haiyan":
return None
raise 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 widgets app = 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.EmailField
label='邮箱',
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 md5 app = Flask(__name__, template_folder='templates')
app.debug = True class MyCSRF(CSRF):
"""
Generate a CSRF token based on the user's IP. I am probably not very
secure, so don't use me.
""" def setup_form(self, form):
self.csrf_context = form.meta.csrf_context()
self.csrf_secret = form.meta.csrf_secret
return super(MyCSRF, self).setup_form(form) def generate_csrf_token(self, csrf_token):
gid = self.csrf_secret + self.csrf_context
token = md5(gid.encode('utf-8')).hexdigest()
return token def 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标签name
csrf_field_name = 'csrf_token' # 自动生成标签的值,加密用的csrf_secret
csrf_secret = 'xxxxxx'
# 自动生成标签的值,加密用的csrf_context
csrf_context = lambda x: request.url
# 生成和比较csrf标签
csrf_class = MyCSRF # -- i18n
# 是否支持本地化
# locales = False
locales = ('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()
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 widgets app = 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.EmailField
label='邮箱',
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()
Flask系列(七)Flask中的wtforms使用的更多相关文章
- iOS流布局UICollectionView系列七——三维中的球型布局
摘要: 类似标签云的球状布局,也类似与魔方的3D布局 iOS流布局UICollectionView系列七——三维中的球型布局 一.引言 通过6篇的博客,从平面上最简单的规则摆放的布局,到不规则的瀑 ...
- Flask系列(二)Flask基础
知识点回顾 1.flask依赖wsgi,实现wsgi的模块:wsgiref(django),werkzeug(flask),uwsgi(上线) 2.实例化Flask对象,里面是有参数的 app = F ...
- Flask系列(六)Flask实例化补充及信号
一.实例化补充 instance_path和instance_relative_config是配合来用的. 这两个参数是用来找配置文件的,当用app.config.from_pyfile('setti ...
- Flask系列之蓝图中使用动态URL前缀
让我们先来看一个简单的例子,假设有下面这样一个蓝图(是关于用户主页的): from flask import Blueprint, render_template profile = Blueprin ...
- flask系列七之cookie和session
该部分参考链接: http://blog.csdn.net/qq_28877125/article/details/77677890 http://blog.csdn.net/qq_28877125/ ...
- Flask系列06--(中间件)Flask的特殊装饰器 before_request,after_request, errorhandler
一.使用 Flask中的特殊装饰器(中间件)方法常用的有三个 @app.before_request # 在请求进入视图函数之前 @app.after_request # 在请求结束视图函数之后 响应 ...
- Flask系列(四)Flask实现简单页面登陆
from flask import Flask,render_template,request,redirect,session app = Flask(__name__,template_folde ...
- Flask系列(五)Flask实现分页
一.flask分页组件 from urllib.parse import urlencode,quote,unquote class Pagination(object): ""& ...
- Spark系列(七)Master中的资源调度
资源调度 说明: Application的调度算法有两种,分别为spreadOutApps和非spreadOutApps spreadOutApps 在spark-submit脚本中,可以指定要多少个 ...
随机推荐
- jQuery弹出层效果
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta ...
- zookeeper 系列文章
http://blog.csdn.net/tswisdom/article/details/41522069 http://blog.csdn.net/tswisdom/article/details ...
- 如何在 React Native 中写一个自定义模块
https://my.oschina.net/jpushtech/blog/983230
- centos7 安装zookeeper 集群
data 创建myid 设置1 zookeeper默认端口2181 同步端口 20881 和 30881 设置zoo.cfg文件
- UVA 1203 - Argus(优先队列)
UVA 1203 - Argus 题目链接 题意:给定一些注冊命令.表示每隔时间t,运行一次编号num的指令.注冊命令结束后.给定k.输出前k个运行顺序 思路:用优先队列去搞,任务时间作为优先级.每次 ...
- 【VR】Leap Motion 官网文档 FingerModel (手指模型)
前言: 感谢关注和支持这个Leap Motion系列翻译的朋友们,非常抱歉因为工作原因非常久没有更新,今后这个翻译还会继续(除非官方直接给出中文文档).本篇献给大家的是 <FingerModel ...
- ftp简单命令
1.连接ftp ftp 192.168.10.15 进去后输入用户名 ,然后再输入密码,就这样登陆成功了,你会看到 ftp> 2.进入ftp后,你对目录需要切换操作.和linux一样的命令.cd ...
- java基础---->Base64算法的使用
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,可用于在HTTP环境下传递较长的标识信息.详细的Base64信息,可以参见维基百科:https://en.wikipedia.org ...
- stringstream读入每行数据
做了下阿里的编程测试题,就30分钟,不是正常的输入输入,直接给一个数组作为输入. 于是带想题和处理数据花了20分钟,最后10分钟搞一个dij模版, 竟然只过了66%,应该是我数组开小了. 题目数据量没 ...
- 学习Ruby你需要了解的相关知识(rvm, gem, bundle, rake, rails等)
这篇文章主要介绍了学习Ruby你需要了解的相关知识(rvm, gem, bundle, rake, rails等),需要的朋友可以参考下 Ruby 这个就不用多说了 RVM 用于帮你安装Rub ...