Flask学习【第7篇】:Flask中的wtforms使用
简介flask中的wtforms
WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。
安装
- pip3 install wtforms
简单使用wtforms组件
用户登录
具体代码:
- 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>
用户注册
- 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>
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()
Flask学习【第7篇】:Flask中的wtforms使用的更多相关文章
- python flask学习第2天 URL中两种方式传参
新创建项目 自己写个url映射到自定义的视图函数 在url中传递参数 app.py from flask import Flask app = Flask(__name__) @app.route ...
- Struts2学习笔记 - Action篇<配置文件中使用通配符>
有三种方法可以使一个Action处理多个请求 动态方法调用DMI 定义逻辑Acton 在配置文件中使用通配符 这里就说一下在配置文件中使用通配符,这里的关键就是struts.xml配置文件,在最简单的 ...
- Android学习笔记(第二篇)View中的五大布局
PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念 view是什么呢?我们已经知道一个Act ...
- Python学习第六篇——字典中的键和值
favorite_language ={ "jen":"python", "sarah":"c", "edwa ...
- Flask 学习篇二:学习Flask过程中的记录
Flask学习笔记: GitHub上面的Flask实践项目 https://github.com/SilentCC/FlaskWeb 1.Application and Request Context ...
- Flask学习【第6篇】:Flask中的信号
实例化补充 instance_path和instance_relative_config是配合来用的.这两个参数是用来找配置文件的,当用app.config.from_pyfile('settings ...
- 第三篇 Flask 中的 request
第三篇 Flask 中的 request 每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前 ...
- 第二篇 Flask 中的 Render Redirect HttpResponse
第二篇 Flask 中的 Render Redirect HttpResponse 1.Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返 ...
- 第九篇 Flask 中的蓝图(BluePrint)
第九篇 Flask 中的蓝图(BluePrint) 蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? ...
随机推荐
- UGUI 打图集
using UnityEngine; using System.Collections; using UnityEditor; using System.Collections.Generic; us ...
- [ English ] 俚语 “Ping me=打我电话”
有次做项目的时候跟一个美国人通过MSN讨论一个问题.突然他说了一句,“Can you ping me in 15 minutes?” Ping Me,什么意思啊? 首先我们来看看“Ping”的原意: ...
- binTreepreorderTraversal二叉树前序遍历
原题 Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binar ...
- 未能正确加载“EditorPackage”包(转)
打开vs2012加载项目的时候报如下的错误: 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包.此问题可能是由配置 ...
- JavaScript(四):运算符&数据类型转换
+:算符的加法:连接字符串 加法会将其它类型的值,自动转为字符串,然后再进行连接运算! var a=1+2; console.log('first: '+a); var a=1+2+'3';//先计算 ...
- sitecore系统教程之架构概述
Sitecore体验数据库(xDB)从实时大数据存储库中的所有通道源收集所有客户交互.它连接交互数据,为每个客户创建全面,统一的视图,并使营销人员可以使用数据来管理客户的实时体验. xDB架构非常灵活 ...
- jQuery属性--addClass()和removeClass()
addClass(class|fn) 概述 为每个匹配的元素添加指定的类名 参数 class 一个或多个要添加到元素中的CSS类名,请用空格分开: function(index, class) ...
- 即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】
像QQ这样的即时通信软件,时不时就会从桌面的右下角弹出一个小窗口,或是显示一个广告.或是一个新闻.或是一个公告等.在这里,我们将其统称为“全局系统通知”.很多使用C#开源即时通讯系统——GGTalk的 ...
- 设计模式之Composite(组合)(转)
Composite定义: 将对象以树形结构组织起来,以达成"部分-整体" 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Comp ...
- java 数组和集合
1.概念说明 区别:数组固定长度的,集合,数组的长度是可以变化的. List,继承Collection,可重复.有序的对象 Set,继承Collection,不可重复.无序的对象 Map,键值对,提供 ...