#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import tornado.web
import tornado.ioloop
import re
class BaseForm(object):
def check_valid(self, handle):
flag = True
error_message_dict = {}
success_value_dict = {}
for key, regular in self.__dict__.items():
input_value = handle.get_argument(key)
# val = re.match(regular, input_value)
# 把验证方法封装到IPField的对象中
regular.validate(key, input_value)
if regular.is_valid:
success_value_dict[key] = regular.value
else:
error_message_dict[key] = regular.error
flag = False
return flag, success_value_dict, error_message_dict
# 总结:客户端把数据post到服务器端,触发handler的post函数,首先实例化MainForm这个类,得到
# 其对象obj。然后obj调用check_valid(self)方法,并把IndexHandler这个类的对象作为参数传进去,
# check_valid是每个Form都具有的方法,所以抽象出一个BaseForm类,让其他Form类都继承这个类,
# 因此其他Form类的对象也可以调用check_valid方法,当obj调用该方法,先循环obj对象所被封装类的
# 属性,得出一个包含ip,host属性名和IPField,HOSTField的对象的一个字典,对应的是key和regular,
# 以IPField为例,regular就是IPField实例化后的对象,一开始我们是在check_valid这个方法里直接
# 验证所有输入的值,现在转移到IPField的方法里去验证,现在调用check_valid是间接的去验证输入的值,
# 也就是regular.validate(key, input_value),这里我觉得关键是self.__dict__,所有都是围绕它
# 的键值对来操作,只不过regular由原先的正则表达式换成类实例化的对象,而正则表达式也封装到这个类
# 里面,并且这个类的对象通过调用这个类的方法来验证客户端输入的信息
class MainForm(BaseForm):
def __init__(self):
self.ip = IPField(required=True, error_dict={"required": "别闹", "valid": "格式错误"})
self.favor = ChechBoxFiled(required=True, error_dict={'required': "复选框不能为空"})
class IPField():
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, error_dict=None, required=True):
self.error_dict = {}
if error_dict:
self.error_dict.update(error_dict)
self.required = required
self.error = None
self.is_valid = False
self.value = None
def validate(self, name, input_value):
if not self.required:
# 如果输入的值可以为空,
self.is_valid = True
self.value = input_value
else:
# 如果要求输入的值不能为空
if not input_value.strip():
# 如果我输入的值是空值,然后我就去取error_dict里面required对应的值
if self.error_dict.get("required", None):
# 如果在生成IPField对象的时候有初始化required的值,则应用该值
self.error = self.error_dict["required"]
else:
# 否则,默认把ip is required赋值到self.error
self.error = "%s is required" % name
else:
# 如果我输入的值不是空值,那么我就要和正则表达式进行比较
ret = re.match(IPField.REGULAR, input_value)
if ret:
self.is_valid = True
# self.value = ret.group()
self.value = input_value
else:
if self.error_dict.get("valid", None):
self.error = self.error_dict["valid"]
else:
self.error = "%s is invalid" % name
class ChechBoxFiled:
def __init__(self, error_dict=None, required=True):
# 封装了错误信息
self.error_dict = {}
if error_dict:
self.error_dict.update(error_dict)
self.required = required
self.error = None # 错误信息
self.value = None
self.is_valid = False
def validate(self, name, input_value):
"""
:param name: 字段名 favor
:param input_value: 用户表单中输入的内容,列表None, [1,2]
:return:
"""
if not self.required:
# 用户输入可以为空
self.is_valid = True
self.value = input_value
else:
if not input_value:
if self.error_dict.get('required', None):
self.error = self.error_dict['required']
else:
self.error = "%s is required" % name
else:
self.is_valid = True
self.value = input_value
class IndexHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.render("index.html", error_dict=None)
def post(self, *args, **kwargs):
obj = MainForm()
is_valid, success_dict, error_dict = obj.check_valid(self)
if is_valid:
print("success", success_dict)
else:
print("error", error_dict)
self.render("index.html", error_dict=error_dict)
settings = {
"template_path": "views",
"static_path": "Statics",
"static_url_prefix": "/Statics/",
}
application = tornado.web.Application([
(r"/index", IndexHandler)
], **settings)
if __name__ == '__main__':
application.listen(9001)
tornado.ioloop.IOLoop.instance().start()