在这里,我们把form表单验证的代码进行工具化了,以后稍微修改一下参数就可以拿来用了

  先贴上代码

forms.py

from backend.form import fields

class BaseForm:

    def __init__(self):
self._value_dict = {}
self._error_dict = {}
self._valid_status = True def valid(self, handler): for field_name, field_obj in self.__dict__.items():
if field_name.startswith('_'):
continue if type(field_obj) == fields.CheckBoxField:
post_value = handler.get_arguments(field_name, None)
elif type(field_obj) == fields.FileField:
post_value = []
file_list = handler.request.files.get(field_name, [])
for file_item in file_list:
post_value.append(file_item['filename'])
else:
post_value = handler.get_argument(field_name, None) field_obj.match(field_name, post_value)
if field_obj.is_valid:
self._value_dict[field_name] = field_obj.value
else:
self._error_dict[field_name] = field_obj.error
self._valid_status = False
return self._valid_status

fields.py

import re
import os class Field: def __init__(self): self.is_valid = False
self.name = None
self.value = None
self.error = None def match(self, name, value):
self.name = name if not self.required:
self.is_valid = True
self.value = value
else:
if not value:
if self.custom_error_dict.get('required', None):
self.error = self.custom_error_dict['required']
else:
self.error = "%s is required" % name
else:
ret = re.match(self.REGULAR, value)
if ret:
self.is_valid = True
self.value = value
else:
if self.custom_error_dict.get('valid', None):
self.error = self.custom_error_dict['valid']
else:
self.error = "%s is invalid" % name class StringField(Field): REGULAR = "^.*$" def __init__(self, custom_error_dict=None, required=True): self.custom_error_dict = {} # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
if custom_error_dict:
self.custom_error_dict.update(custom_error_dict) self.required = required super(StringField, self).__init__() class IPField(Field): REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$" def __init__(self, custom_error_dict=None, required=True): self.custom_error_dict = {} # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
if custom_error_dict:
self.custom_error_dict.update(custom_error_dict) self.required = required
super(IPField, self).__init__() class EmailField(Field): REGULAR = "^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$" def __init__(self, custom_error_dict=None, required=True): self.custom_error_dict = {} # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
if custom_error_dict:
self.custom_error_dict.update(custom_error_dict) self.required = required
super(EmailField, self).__init__() class IntegerField(Field): REGULAR = "^\d+$" def __init__(self, custom_error_dict=None, required=True): self.custom_error_dict = {} # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
if custom_error_dict:
self.custom_error_dict.update(custom_error_dict) self.required = required
super(IntegerField, self).__init__() class CheckBoxField(Field): REGULAR = "^\d+$" def __init__(self, custom_error_dict=None, required=True): self.custom_error_dict = {} # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
if custom_error_dict:
self.custom_error_dict.update(custom_error_dict) self.required = required
super(CheckBoxField, self).__init__() def match(self, name, value):
self.name = name if not self.required:
self.is_valid = True
self.value = value
else:
if not value:
if self.custom_error_dict.get('required', None):
self.error = self.custom_error_dict['required']
else:
self.error = "%s is required" % name
else:
if isinstance(name, list):
self.is_valid = True
self.value = value
else:
if self.custom_error_dict.get('valid', None):
self.error = self.custom_error_dict['valid']
else:
self.error = "%s is invalid" % name class FileField(Field): REGULAR = "^(\w+\.pdf)|(\w+\.mp3)|(\w+\.py)$" def __init__(self, custom_error_dict=None, required=True): self.custom_error_dict = {} # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
if custom_error_dict:
self.custom_error_dict.update(custom_error_dict) self.required = required super(FileField, self).__init__() def match(self, name, file_name_list):
flag = True
self.name = name if not self.required:
self.is_valid = True
self.value = file_name_list
else:
if not file_name_list:
if self.custom_error_dict.get('required', None):
self.error = self.custom_error_dict['required']
else:
self.error = "%s is required" % name
flag = False
else:
for file_name in file_name_list:
if not file_name or not file_name.strip():
if self.custom_error_dict.get('required', None):
self.error = self.custom_error_dict['required']
else:
self.error = "%s is required" % name
flag = False
break
else:
ret = re.match(self.REGULAR, file_name)
if not ret:
if self.custom_error_dict.get('valid', None):
self.error = self.custom_error_dict['valid']
else:
self.error = "%s is invalid" % name
flag = False
break self.is_valid = flag def save(self, request, upload_to=""): file_metas = request.files[self.name]
for meta in file_metas:
file_name = meta['filename']
file_path_name = os.path.join(upload_to, file_name)
with open(file_path_name, 'wb') as up:
up.write(meta['body']) upload_file_path_list = map(lambda path: os.path.join(upload_to, path), self.value)
self.value = list(upload_file_path_list)

在form.py这个文件,做了一件什么事呢?代码就定义了父类,主要是判断要验证内容的类型,然后取值,然后又调用了在fields.py里类的match方法,最后把验证后结果信息返回(vaild方法)。

  而在fields.py文件里,主要是对为空检测,合法性检测,并把检测结果返回给form.py的vaild方法里(match方法)

首先

  • form组件只做为空检测,合法性检测,并没做超时检测,内部可获取验证状态_valid_status--True/False,错误信息_error_dict,验证通过时的用户数据_value_dict

  • 验证类型:字符串,IP,邮箱,数字,复选框,文件

再者,怎么用?

  • 分析你的应用场景,需要对哪几个类型进行验证,定义一个类,把需要的验证类型写入到构造方法里,记得继承一下BaseForm类,并且继承一下父类的构造方法

  • 在构造方法里,实例Field对象时,可以传入自定制错误类型信息custom_error_dict,required=False可为空设置

    from backend.form.forms import BaseForm
    from backend.form.fields import StringField
    from backend.form.fields import IntegerField
    from backend.form.fields import EmailField class SendMsgForm(BaseForm): def __init__(self):
    self.email = EmailField(custom_error_dict={'required': '注册邮箱不能为空.', 'valid': '注册邮箱格式错误.'}) super(SendMsgForm, self).__init__() class RegisterForm(BaseForm): def __init__(self):
    self.username = StringField()
    self.email = EmailField()
    self.password = StringField()
    self.email_code = StringField() super(RegisterForm, self).__init__() class LoginForm(BaseForm): def __init__(self):
    self.user = StringField()
    self.pwd = StringField()
    self.code = StringField() super(LoginForm, self).__init__()

    最后

    • 在post方法里,调用一下form对象的vaild方法(把handler对象,也就是self传入),接下来只要根据form对象里检测完后的信息进行相应的操作

import io
import datetime
import json
from backend.utils import check_code
from backend.core.request_handler import BaseRequestHandler
from forms import account
from backend.utils.response import BaseResponse
from backend import commons
from models import chouti_orm as ORM
from sqlalchemy import and_, or_ class CheckCodeHandler(BaseRequestHandler):
def get(self, *args, **kwargs):
stream = io.BytesIO()
img, code = check_code.create_validate_code()
img.save(stream, "png")
self.session["CheckCode"] = code
self.write(stream.getvalue()) class LoginHandler(BaseRequestHandler):
def post(self, *args, **kwargs):
#对象里有self.status=False,self.data=None,self.summary=None,self.message={}
rep = BaseResponse()
form = account.LoginForm()
if form.valid(self):
if form._value_dict['code'].lower() != self.session["CheckCode"].lower():
rep.message = {'code': '验证码错误'}
self.write(json.dumps(rep.__dict__))
return
conn = ORM.session()
obj = conn.query(ORM.UserInfo).filter(
or_(
and_(ORM.UserInfo.email == form._value_dict['user'],
ORM.UserInfo.password == form._value_dict['pwd']),
and_(ORM.UserInfo.username == form._value_dict['user'],
ORM.UserInfo.password == form._value_dict['pwd'])
)).first()
if not obj:
rep.message = {'user': '用户名邮箱或密码错误'}
self.write(json.dumps(rep.__dict__))
return self.session['is_login'] = True
self.session['user_info'] = obj.__dict__
rep.status = True
else:
rep.message = form._error_dict
self.write(json.dumps(rep.__dict__)) class RegisterHandler(BaseRequestHandler):
def post(self, *args, **kwargs):
rep = BaseResponse()
form = account.RegisterForm()
if form.valid(self):
current_date = datetime.datetime.now()
limit_day = current_date - datetime.timedelta(minutes=1)
conn = ORM.session()
is_valid_code = conn.query(ORM.SendMsg).filter(ORM.SendMsg.email == form._value_dict['email'],
ORM.SendMsg.code == form._value_dict['email_code'],
ORM.SendMsg.ctime > limit_day).count()
if not is_valid_code:
rep.message['email_code'] = '邮箱验证码不正确或过期'
self.write(json.dumps(rep.__dict__))
return
has_exists_email = conn.query(ORM.UserInfo).filter(ORM.UserInfo.email == form._value_dict['email']).count()
if has_exists_email:
rep.message['email'] = '邮箱已经存在'
self.write(json.dumps(rep.__dict__))
return
has_exists_username = conn.query(ORM.UserInfo).filter(
ORM.UserInfo.username == form._value_dict['username']).count()
if has_exists_username:
rep.message['email'] = '用户名已经存在'
self.write(json.dumps(rep.__dict__))
return
form._value_dict['ctime'] = current_date
form._value_dict.pop('email_code')
obj = ORM.UserInfo(**form._value_dict)
conn.add(obj)
conn.query(ORM.SendMsg).filter_by(email=form._value_dict['email']).delete()
conn.commit()
self.session['is_login'] = True
self.session['user_info'] = obj.__dict__
rep.status = True else:
rep.message = form._error_dict self.write(json.dumps(rep.__dict__)) class SendMsgHandler(BaseRequestHandler):
def post(self, *args, **kwargs):
rep = BaseResponse()
form = account.SendMsgForm()
if form.valid(self):
email = form._value_dict['email']
conn = ORM.session() has_exists_email = conn.query(ORM.UserInfo).filter(ORM.UserInfo.email == form._value_dict['email']).count()
if has_exists_email:
rep.summary = "此邮箱已经被注册"
self.write(json.dumps(rep.__dict__))
return
current_date = datetime.datetime.now()
code = commons.random_code() count = conn.query(ORM.SendMsg).filter_by(**form._value_dict).count()
if not count:
insert = ORM.SendMsg(code=code,
email=email,
ctime=current_date)
conn.add(insert)
conn.commit()
rep.status = True
else:
limit_day = current_date - datetime.timedelta(hours=1)
times = conn.query(ORM.SendMsg).filter(ORM.SendMsg.email == email,
ORM.SendMsg.ctime > limit_day,
ORM.SendMsg.times >= 10,
).count()
if times:
rep.summary = "'已经超过今日最大次数(1小时后重试)'"
else:
unfreeze = conn.query(ORM.SendMsg).filter(ORM.SendMsg.email == email,
ORM.SendMsg.ctime < limit_day).count()
if unfreeze:
conn.query(ORM.SendMsg).filter_by(email=email).update({"times": 0}) conn.query(ORM.SendMsg).filter_by(email=email).update({"times": ORM.SendMsg.times + 1,
"code": code,
"ctime": current_date},
synchronize_session="evaluate")
conn.commit()
rep.status = True
else:
rep.summary = form._error_dict['email']
self.write(json.dumps(rep.__dict__))

抽屉之Tornado实战(7)--form表单验证的更多相关文章

  1. tornado之自定义form表单验证

    直接上链接吧:银角的地址 源码下载链接:点我点我点我...

  2. python26:自定义form表单验证

    一.自定义Form的原理 1.1 各种form表单验证比较 只有python提供了form表单验证,其他的都没有提供.django提供的功能还不够强大.最强大的是微软的ASP.NET!我们可以自己写一 ...

  3. 看用Tornado如何自定义实现表单验证

    我们知道,平时在登陆某个网站或软件时,网站对于你输入的内容是有要求的,并且会对你输入的错误内容有提示,对于Django这种大而全的web框架,是提供了form表单验证功能,但是对于Tornado而言, ...

  4. Form表单验证组件

    Tyrion是一个基于Python实现的支持多个WEB框架的Form表单验证组件,其完美的支持Tornado.Django.Flask.Bottle Web框架.Tyrion主要有两大重要动能: 表单 ...

  5. form表单验证-Javascript

    Form表单验证: js基础考试内容,form表单验证,正则表达式,blur事件,自动获取数组,以及css布局样式,动态清除等.完整代码如下: <!DOCTYPE html PUBLIC &qu ...

  6. django之form表单验证

    django中的Form一般有两种功能: 输入html 验证用户输入 #!/usr/bin/env python # -*- coding:utf- -*- import re from django ...

  7. python_way day19 HTML-day5 (form表单验证,CSRF,cookie,session,缓存)

    python-way day19 1. dJango的form表单验证 2.CSRF 跨站请求伪造 3.cookie,session 4.缓存 一,django表单验证功能 1.django验证基础: ...

  8. form表单验证2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Day19 Django之Form表单验证、CSRF、Cookie、Session和Model操作

    一.Form表单验证 用于做用户提交数据的验证1.自定义规则 a.自定义规则(类,字段名==html中的name值)b.数据提交-规则进行匹配代码如下: """day19 ...

随机推荐

  1. Unity的Attribute(特性)还算多吧

    属性 (Attribute) 使用 Unity 的C#语言 ,利用属性(Attribute)来类定义和变量定义或区分其他的变量,您可以设置一种特殊行为.* 1 例如,您添加[SerializeFiel ...

  2. 在Centos 6 64bit 上安装 Hyperic HQ 5.8.2.1 中文版

    原文:https://my.oschina.net/hyperichq/blog/306791 环境描述: [test@tester ~]$ cat /etc/issue CentOS release ...

  3. Odoo小数精度及货币精度详解

    一.小数精度的设置 一般在设置-数据结构-精度设置中就可以对 小数类型的字段进行精度设置: 对于代码中定义为 digits=dp.get_precision('Product Price') 或 di ...

  4. Why you should use async tasks in .NET 4.5 and Entity Framework 6

    Improve response times and handle more users with parallel processing Building a web application usi ...

  5. C艹目录

    c++ 学习路线  c++学习路线 c++ 学习目录 c++ 常用数据类型,命名规则, 不常有数据类型 C++复合类型(数组) C艹复合类型(字符串) C++复合类型(结构体) C++ 结构体和枚举 ...

  6. psd页面切割成html技巧总结

    关键字:psd切割技巧 生成html图片要点 css样式要点 rem 与高手切割后的代码对比学习提高(考察点:切割后的页面质量,源码大小及图片大小,js技术,动画技术,开发和命名规范等) 一.psd切 ...

  7. Cisco NTP配置

    Windows 或 Linux 系统配置成NTP服务器,思科交换机配置成NTP客户端 ##创建VLAN 10 SW01>enable SW01#vlan database SW01(vlan)# ...

  8. 树莓派集群实践2——修改树莓派3 指定IP,DNS要修改dhcpcd.conf

    vim /etc/dhcpcd.conf 修改如下 interface eth0 static ip_address=192.168.1.177/24 static routers=192.168.1 ...

  9. nginx 默认访问index.php

    代码 http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; #k ...

  10. Python 中的map、reduce函数用法

    #-*- coding:UTF-8 -*- #map()函数接受两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回 def f(x): retu ...