简介flask中的wtforms

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

安装

  1. pip3 install wtforms

简单使用wtforms组件

用户登录

具体代码:

  1. from flask import Flask,render_template,request,redirect
  2. from wtforms.fields import core
  3. from wtforms.fields import html5
  4. from wtforms.fields import simple
  5. from wtforms import Form
  6. from wtforms import validators
  7. from wtforms import widgets
  8. app = Flask(__name__,template_folder="templates")
  9.  
  10. class Myvalidators(object):
  11. '''自定义验证规则'''
  12. def __init__(self,message):
  13. self.message = message
  14. def __call__(self, form, field):
  15. print(field.data,"用户输入的信息")
  16. if field.data == "haiyan":
  17. return None
  18. raise validators.ValidationError(self.message)
  19.  
  20. class LoginForm(Form):
  21. '''Form'''
  22. name = simple.StringField(
  23. label="用户名",
  24. widget=widgets.TextInput(),
  25. validators=[
  26. Myvalidators(message="用户名必须是haiyan"),#也可以自定义正则
  27. validators.DataRequired(message="用户名不能为空"),
  28. validators.Length(max=8,min=3,message="用户名长度必须大于%(max)d且小于%(min)d")
  29. ],
  30. render_kw={"class":"form-control"} #设置属性
  31. )
  32.  
  33. pwd = simple.PasswordField(
  34. label="密码",
  35. validators=[
  36. validators.DataRequired(message="密码不能为空"),
  37. validators.Length(max=8,min=3,message="密码长度必须大于%(max)d且小于%(min)d"),
  38. validators.Regexp(regex="\d+",message="密码必须是数字"),
  39. ],
  40. widget=widgets.PasswordInput(),
  41. render_kw={"class":"form-control"}
  42. )
  43.  
  44. @app.route('/login',methods=["GET","POST"])
  45. def login():
  46. if request.method =="GET":
  47. form = LoginForm()
  48. return render_template("login.html",form=form)
  49. else:
  50. form = LoginForm(formdata=request.form)
  51. if form.validate():
  52. print("用户提交的数据用过格式验证,值为:%s"%form.data)
  53. return "登录成功"
  54. else:
  55. print(form.errors,"错误信息")
  56. return render_template("login.html",form=form)
  57.  
  58. if __name__ == '__main__':
  59. # app.__call__()
  60. app.run(debug=True)

login.html

  1. <body>
  2. <form action="" method="post" novalidate>
  3. <p>{{ form.name.label }} {{ form.name }} {{ form.name.errors.0 }}</p>
  4. <p>{{ form.pwd.label }} {{ form.pwd }} {{ form.pwd.errors.0 }}</p>
  5. <input type="submit" value="提交">
  6. <!--用户名:<input type="text">-->
  7. <!--密码:<input type="password">-->
  8. <!--<input type="submit" value="提交">-->
  9. </form>
  10. </body>

用户注册

  1. from flask import Flask,render_template,redirect,request
  2. from wtforms import Form
  3. from wtforms.fields import core
  4. from wtforms.fields import html5
  5. from wtforms.fields import simple
  6. from wtforms import validators
  7. from wtforms import widgets
  8.  
  9. app = Flask(__name__,template_folder="templates")
  10. app.debug = True
  11.  
  12. =======================simple===========================
  13. class RegisterForm(Form):
  14. name = simple.StringField(
  15. label="用户名",
  16. validators=[
  17. validators.DataRequired()
  18. ],
  19. widget=widgets.TextInput(),
  20. render_kw={"class":"form-control"},
  21. default="haiyan"
  22. )
  23. pwd = simple.PasswordField(
  24. label="密码",
  25. validators=[
  26. validators.DataRequired(message="密码不能为空")
  27. ]
  28. )
  29. pwd_confim = simple.PasswordField(
  30. label="重复密码",
  31. validators=[
  32. validators.DataRequired(message='重复密码不能为空.'),
  33. validators.EqualTo('pwd',message="两次密码不一致")
  34. ],
  35. widget=widgets.PasswordInput(),
  36. render_kw={'class': 'form-control'}
  37. )
  38.  
  39.   ========================html5============================
  40. email = html5.EmailField( #注意这里用的是html5.EmailField
  41. label='邮箱',
  42. validators=[
  43. validators.DataRequired(message='邮箱不能为空.'),
  44. validators.Email(message='邮箱格式错误')
  45. ],
  46. widget=widgets.TextInput(input_type='email'),
  47. render_kw={'class': 'form-control'}
  48. )
  49.  
  50.   ===================以下是用core来调用的=======================
  51. gender = core.RadioField(
  52. label="性别",
  53. choices=(
  54. (1,"男"),
  55. (1,"女"),
  56. ),
  57. coerce=int #限制是int类型的
  58. )
  59. city = core.SelectField(
  60. label="城市",
  61. choices=(
  62. ("bj","北京"),
  63. ("sh","上海"),
  64. )
  65. )
  66. hobby = core.SelectMultipleField(
  67. label='爱好',
  68. choices=(
  69. (1, '篮球'),
  70. (2, '足球'),
  71. ),
  72. coerce=int
  73. )
  74. favor = core.SelectMultipleField(
  75. label="喜好",
  76. choices=(
  77. (1, '篮球'),
  78. (2, '足球'),
  79. ),
  80. widget = widgets.ListWidget(prefix_label=False),
  81. option_widget = widgets.CheckboxInput(),
  82. coerce = int,
  83. default = [1, 2]
  84. )
  85.  
  86. def __init__(self,*args,**kwargs): #这里的self是一个RegisterForm对象
  87. '''重写__init__方法'''
  88. super(RegisterForm,self).__init__(*args, **kwargs) #继承父类的init方法
  89. self.favor.choices =((1, '篮球'), (2, '足球'), (3, '羽毛球')) #吧RegisterForm这个类里面的favor重新赋值
  90.  
  91. def validate_pwd_confim(self,field,):
  92. '''
  93. 自定义pwd_config字段规则,例:与pwd字段是否一致
  94. :param field:
  95. :return:
  96. '''
  97. # 最开始初始化时,self.data中已经有所有的值
  98. if field.data != self.data['pwd']:
  99. # raise validators.ValidationError("密码不一致") # 继续后续验证
  100. raise validators.StopValidation("密码不一致") # 不再继续后续验证
  101.  
  102. @app.route('/register',methods=["GET","POST"])
  103. def register():
  104. if request.method=="GET":
  105. form = RegisterForm(data={'gender': 1}) #默认是1,
  106. return render_template("register.html",form=form)
  107. else:
  108. form = RegisterForm(formdata=request.form)
  109. if form.validate(): #判断是否验证成功
  110. print('用户提交数据通过格式验证,提交的值为:', form.data) #所有的正确信息
  111. else:
  112. print(form.errors) #所有的错误信息
  113. return render_template('register.html', form=form)
  114.  
  115. if __name__ == '__main__':
  116. app.run()

register.html

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

meta

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from flask import Flask, render_template, request, redirect, session
  4. from wtforms import Form
  5. from wtforms.csrf.core import CSRF
  6. from wtforms.fields import core
  7. from wtforms.fields import html5
  8. from wtforms.fields import simple
  9. from wtforms import validators
  10. from wtforms import widgets
  11. from hashlib import md5
  12.  
  13. app = Flask(__name__, template_folder='templates')
  14. app.debug = True
  15.  
  16. class MyCSRF(CSRF):
  17. """
  18. Generate a CSRF token based on the user's IP. I am probably not very
  19. secure, so don't use me.
  20. """
  21.  
  22. def setup_form(self, form):
  23. self.csrf_context = form.meta.csrf_context()
  24. self.csrf_secret = form.meta.csrf_secret
  25. return super(MyCSRF, self).setup_form(form)
  26.  
  27. def generate_csrf_token(self, csrf_token):
  28. gid = self.csrf_secret + self.csrf_context
  29. token = md5(gid.encode('utf-8')).hexdigest()
  30. return token
  31.  
  32. def validate_csrf_token(self, form, field):
  33. print(field.data, field.current_token)
  34. if field.data != field.current_token:
  35. raise ValueError('Invalid CSRF')
  36.  
  37. class TestForm(Form):
  38. name = html5.EmailField(label='用户名')
  39. pwd = simple.StringField(label='密码')
  40.  
  41. class Meta:
  42. # -- CSRF
  43. # 是否自动生成CSRF标签
  44. csrf = True
  45. # 生成CSRF标签name
  46. csrf_field_name = 'csrf_token'
  47.  
  48. # 自动生成标签的值,加密用的csrf_secret
  49. csrf_secret = 'xxxxxx'
  50. # 自动生成标签的值,加密用的csrf_context
  51. csrf_context = lambda x: request.url
  52. # 生成和比较csrf标签
  53. csrf_class = MyCSRF
  54.  
  55. # -- i18n
  56. # 是否支持本地化
  57. # locales = False
  58. locales = ('zh', 'en')
  59. # 是否对本地化进行缓存
  60. cache_translations = True
  61. # 保存本地化缓存信息的字段
  62. translations_cache = {}
  63.  
  64. @app.route('/index/', methods=['GET', 'POST'])
  65. def index():
  66. if request.method == 'GET':
  67. form = TestForm()
  68. else:
  69. form = TestForm(formdata=request.form)
  70. if form.validate():
  71. print(form)
  72. return render_template('index.html', form=form)
  73.  
  74. if __name__ == '__main__':
  75. app.run()

  

Flask学习【第7篇】:Flask中的wtforms使用的更多相关文章

  1. python flask学习第2天 URL中两种方式传参

    新创建项目   自己写个url映射到自定义的视图函数 在url中传递参数 app.py from flask import Flask app = Flask(__name__) @app.route ...

  2. Struts2学习笔记 - Action篇<配置文件中使用通配符>

    有三种方法可以使一个Action处理多个请求 动态方法调用DMI 定义逻辑Acton 在配置文件中使用通配符 这里就说一下在配置文件中使用通配符,这里的关键就是struts.xml配置文件,在最简单的 ...

  3. Android学习笔记(第二篇)View中的五大布局

    PS:人不要低估自己的实力,但是也不能高估自己的能力.凡事谦为本... 学习内容: 1.用户界面View中的五大布局... i.首先介绍一下view的概念   view是什么呢?我们已经知道一个Act ...

  4. Python学习第六篇——字典中的键和值

    favorite_language ={ "jen":"python", "sarah":"c", "edwa ...

  5. Flask 学习篇二:学习Flask过程中的记录

    Flask学习笔记: GitHub上面的Flask实践项目 https://github.com/SilentCC/FlaskWeb 1.Application and Request Context ...

  6. Flask学习【第6篇】:Flask中的信号

    实例化补充 instance_path和instance_relative_config是配合来用的.这两个参数是用来找配置文件的,当用app.config.from_pyfile('settings ...

  7. 第三篇 Flask 中的 request

    第三篇 Flask 中的 request   每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前 ...

  8. 第二篇 Flask 中的 Render Redirect HttpResponse

    第二篇 Flask 中的 Render Redirect HttpResponse   1.Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返 ...

  9. 第九篇 Flask 中的蓝图(BluePrint)

    第九篇 Flask 中的蓝图(BluePrint)   蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? ...

随机推荐

  1. UGUI 打图集

    using UnityEngine; using System.Collections; using UnityEditor; using System.Collections.Generic; us ...

  2. [ English ] 俚语 “Ping me=打我电话”

    有次做项目的时候跟一个美国人通过MSN讨论一个问题.突然他说了一句,“Can you ping me in 15 minutes?” Ping Me,什么意思啊? 首先我们来看看“Ping”的原意: ...

  3. binTreepreorderTraversal二叉树前序遍历

    原题 Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binar ...

  4. 未能正确加载“EditorPackage”包(转)

    打开vs2012加载项目的时候报如下的错误: 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包.此问题可能是由配置 ...

  5. JavaScript(四):运算符&数据类型转换

    +:算符的加法:连接字符串 加法会将其它类型的值,自动转为字符串,然后再进行连接运算! var a=1+2; console.log('first: '+a); var a=1+2+'3';//先计算 ...

  6. sitecore系统教程之架构概述

    Sitecore体验数据库(xDB)从实时大数据存储库中的所有通道源收集所有客户交互.它连接交互数据,为每个客户创建全面,统一的视图,并使营销人员可以使用数据来管理客户的实时体验. xDB架构非常灵活 ...

  7. jQuery属性--addClass()和removeClass()

       addClass(class|fn) 概述 为每个匹配的元素添加指定的类名 参数 class  一个或多个要添加到元素中的CSS类名,请用空格分开: function(index, class) ...

  8. 即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】

    像QQ这样的即时通信软件,时不时就会从桌面的右下角弹出一个小窗口,或是显示一个广告.或是一个新闻.或是一个公告等.在这里,我们将其统称为“全局系统通知”.很多使用C#开源即时通讯系统——GGTalk的 ...

  9. 设计模式之Composite(组合)(转)

    Composite定义: 将对象以树形结构组织起来,以达成"部分-整体" 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性. Composite比较容易理解,想到Comp ...

  10. java 数组和集合

    1.概念说明 区别:数组固定长度的,集合,数组的长度是可以变化的. List,继承Collection,可重复.有序的对象 Set,继承Collection,不可重复.无序的对象 Map,键值对,提供 ...