Tyrion是一个基于Python实现的支持多个WEB框架的Form表单验证组件,其完美的支持Tornado、Django、Flask、Bottle Web框架。Tyrion主要有两大重要动能:
- 表单验证
- 生成HTML标签
- 保留上次提交内容
对于表单验证,告别书写重复的正则表达式对用户提交的数据进行验证的工作,从此解放双手,跟着我左手右手一个慢动作…
对于生成HTML标签,不在人工书写html标签,让Tyrion帮你自动创建…
对于保留上次提交内容,由于默认表单提交后页面刷新,原来输入的内容会清空,Tyrion可以保留上次提交内容。
github:https://github.com/WuPeiqi/Tyrion
使用文档
1、下载安装
1 pip install PyTyrion
github: https://github.com/WuPeiqi/Tyrion
2、配置WEB框架种类
由于Tyrion同时支持Tornado、Django、Flask、Bottle多个WEB框架,所有在使用前需要进行指定。
1 import Tyrion
2 Tyrion.setup('tornado')
3 # setup的参数有:tornado(默认)、django、bottle、flask
Form类用于提供验证规则、插件属性、错误信息等
1 from Tyrion.Forms import Form
2 from Tyrion.Fields import StringField
3 from Tyrion.Fields import EmailField
4
5 class LoginForm(Form):
6 username = StringField(error={'required': '用户名不能为空'})
7 password = StringField(error={'required': '密码不能为空'})
8 email = EmailField(error={'required': '邮箱不能为空', 'invalid': '邮箱格式错误'})
4、验证用户请求
前端HTML代码:
1 <form method="POST" action="/login.html">
2 <div>
3 <input type="text" name="username">
4 </div>
5 <div>
6 <input type="text" name="password">
7 </div>
8 <div>
9 <input type="text" name="email">
10 </div>
11
12 <input type="submit" value="提交">
13 </form>
用户提交数据时,在后台书写如下代码即可实现用户请求数据验证(Tornado示例):
1 class LoginHandler(tornado.web.RequestHandler):
2 def get(self, *args, **kwargs):
3 self.render('login.html')
4
5 def post(self, *args, **kwargs):
6 form = LoginForm(self)
7
8 ###### 检查用户输入是否合法 ######
9 if form.is_valid():
10
11 ###### 如果不合法,则输出错误信息 ######
12 print(form.error_dict)
13 else:
14 ###### 如果合法,则输出用户输入的内容 ######
15 print(form.value_dict)
16 self.render('login.html')
示例01:源码下载(含Tornado、Django、Flask、Bottle)
5、验证用户请求 && 生成HTML标签 && 保留上次输入内容 && 错误提示
Tyrion不仅可以验证用户请求,还可以生成自动创建HTML标签并且可以保留用户上次输入的内容。在HTML模板中调用Form类对象的字段即可,如(Tornado示例):
from Tyrion.Forms import Form
from Tyrion.Fields import StringField
from Tyrion.Fields import EmailField
class LoginForm(Form):
username = StringField(error={'required': '用户名不能为空'})
password = StringField(error={'required': '密码不能为空'})
email = EmailField(error={'required': '邮箱不能为空', 'invalid': '邮箱格式错误'})
1 class LoginHandler(tornado.web.RequestHandler):
2 def get(self, *args, **kwargs):
3 form = LoginForm(self)
4 self.render('login.html', form=form)
5
6 def post(self, *args, **kwargs):
7 form = LoginForm(self)
8
9 print(form.is_valid())
10 print(form.error_dict)
11 print(form.value_dict)
12
13 self.render('login.html', form=form)
1 <form method="post" action="/login.html">
2 <div>
3 <!-- Form创建的标签 -->
4 {% raw form.username %}
5
6 <!-- 错误信息 -->
7 <span>{{form.error_dict.get('username',"")}}</span>
8 </div>
9 <div>
10 {% raw form.password %}
11 <span>{{form.error_dict.get('password',"")}}</span>
12 </div>
13 <div>
14 {% raw form.email %}
15 <span>{{form.error_dict.get('email',"")}}</span>
16 </div>
17 <input type="submit" value="提交"/
注意: HTML模板中的转义
示例02:源码下载(含有Tornado、Django、Flask、Bottle)
6、Form字段类型
Form的字段用于指定从请求中获取的数据类型以及格式,以此来验证用户输入的内容。
1 from Tyrion.Forms import Form
2 from Tyrion.Fields import StringField
3 from Tyrion.Fields import EmailField
4
5 class LoginForm(Form):
6 username = StringField(error={'required': '用户名不能为空'})
7 password = StringField(error={'required': '密码不能为空'})
8 email = EmailField(error={'required': '邮箱不能为空', 'invalid': '邮箱格式错误'})
以上代码表示此Form类可以用于验证用户输入的内容,并且 username和password必须不能为空,email必须不能为空并且必须是邮箱格式。
目前支持所有字段:
1 StringField
2 """
3 要求必须是字符串,即:正则^.*$
4
5 参数:
6 required 布尔值,是否允许为空
7 max_length 整数,限制用户输入内容最大长度
8 min_length 整数,限制用户输入内容最小长度
9 error 字典,自定义错误提示,如:{
10 'required': '值为空时的错误提示',
11 'invalid': '格式错误时的错误提示',
12 'max_length': '最大长度为10',
13 'min_length': '最小长度为1',
14 }
15 widget 定制生成的HTML插件(默认InputText)
16 """
17
18 EmailField
19 """
20 要求必须是邮箱格式的字符串
21
22 参数:
23 required 布尔值,是否允许为空
24 max_length 整数,限制用户输入内容最大长度
25 min_length 整数,限制用户输入内容最小长度
26 error 字典,自定义错误提示,如:{
27 'required': '值为空时的错误提示',
28 'invalid': '格式错误时的错误提示',
29 'max_length': '最大长度为10',
30 'min_length': '最小长度为1',
31 }
32 widget 定制生成的HTML插件(默认InputText)
33 """
34
35 IPField
36 """
37 要求必须是IP格式
38
39 参数:
40 required 布尔值,是否允许为空
41 max_length 整数,限制用户输入内容最大长度
42 min_length 整数,限制用户输入内容最小长度
43 error 字典,自定义错误提示,如:{
44 'required': '值为空时的错误提示',
45 'invalid': '格式错误时的错误提示',
46 'max_length': '最大长度为10',
47 'min_length': '最小长度为1',
48 }
49 widget 定制生成的HTML插件(默认InputText)
50
51 """
52
53 IntegerField
54 """
55 要求必须整数格式
56
57 参数:
58 required 布尔值,是否允许为空
59 max_value 整数,限制用户输入数字最大值
60 min_value 整数,限制用户输入数字最小值
61 error 字典,自定义错误提示,如:{
62 'required': '值为空时的错误提示',
63 'invalid': '格式错误时的错误提示',
64 'max_value': '最大值为10',
65 'max_value': '最小值度为1',
66 }
67 widget 定制生成的HTML插件(默认InputText)
68
69 """
70
71 FloatField
72 """
73 要求必须小数格式
74
75 参数:
76 required 布尔值,是否允许为空
77 max_value 整数,限制用户输入数字最大值
78 min_value 整数,限制用户输入数字最小值
79 error 字典,自定义错误提示,如:{
80 'required': '值为空时的错误提示',
81 'invalid': '格式错误时的错误提示',
82 'max_value': '最大值为10',
83 'max_value': '最小值度为1',
84 }
85 widget 定制生成的HTML插件(默认InputText)
86 """
87
88 StringListField
89 """
90 用于获取请求中的多个值,且保证每一个元素是字符串,即:正则^.*$
91 如:checkbox或selct多选时,会提交多个值,用此字段可以将用户提交的值保存至列表
92
93 参数:
94 required 布尔值,是否允许为空
95 ele_max_length 整数,限制用户输入的每个元素内容最大长度
96 ele_min_length 整数,限制用户输入的每个元素内容最小长度
97 error 字典,自定义错误提示,如:{
98 'required': '值为空时的错误提示',
99 'element': '列表中的元素必须是字符串',
100 'ele_max_length': '最大长度为10',
101 'ele_min_length': '最小长度为1',
102 }
103 widget 定制生成的HTML插件(默认InputMultiCheckBox,即:checkbox)
104 """
105
106 IntegerListField
107 """
108 用于获取请求中的多个值,且保证每一个元素是整数
109 如:checkbox或selct多选时,会提交多个值,用此字段可以将用户提交的值保存至列表
110
111 参数:
112 required 布尔值,是否允许为空
113 ele_max_value 整数,限制用户输入的每个元素内容最大长度
114 ele_min_value 整数,限制用户输入的每个元素内容最小长度
115 error 字典,自定义错误提示,如:{
116 'required': '值为空时的错误提示',
117 'element': '列表中的元素必须是数字',
118 'ele_max_value': '最大值为x',
119 'ele_min_value': '最小值为x',
120 }
121 widget 定制生成的HTML插件(默认InputMultiCheckBox,即:checkbox)
122 """
7、Form字段widget参数:HTML插件
HTML插件用于指定当前字段在生成HTML时表现的种类和属性,通过指定此参数从而实现定制页面上生成的HTML标签
1 from Tyrion.Forms import Form
2 from Tyrion.Fields import StringField
3 from Tyrion.Fields import EmailField
4
5 from Tyrion.Widget import InputPassword
6
7 class LoginForm(Form):
8 password = StringField(error={'required': '密码不能为空'},widget=InputPassword())
上述LoginForm的password字段要求用户输入必须是字符串类型,并且指定生成HTML标签时会创建为<input type=’password’ > 标签
目前支持所有插件:
1 InputText
2 """
3 设置Form对应字段在HTML中生成input type='text' 标签
4
5 参数:
6 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1', 'placeholder': 'username'}
7 """
8 InputEmail
9 """
10 设置Form对应字段在HTML中生成input type='email' 标签
11
12 参数:
13 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1', 'placeholder': 'username'}
14 """
15 InputPassword
16 """
17 设置Form对应字段在HTML中生成input type='password' 标签
18
19 参数:
20 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1', 'placeholder': 'username'}
21 """
22 TextArea
23 """
24 设置Form对应字段在HTML中生成 textarea 标签
25
26 参数:
27 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1'}
28 value 字符串,用于设置textarea标签中默认显示的内容
29 """
30
31 InputRadio
32 """
33 设置Form对应字段在HTML中生成一系列 input type='radio' 标签(选择时互斥)
34
35 参数:
36 attr 字典,生成的HTML属性,如:{'class': 'c1'}
37 text_value_list 列表,生成的多个radio标签的内容和值,如:[
38 {'value':1, 'text': '男'},
39 {'value':2, 'text': '女'},
40 ]
41 checked_value 整数或字符串,默认被选中的标签的value的值
42
43 示例:
44 from Tyrion.Forms import Form
45 from Tyrion.Fields import IntegerField
46
47 from Tyrion.Widget import InputRadio
48
49
50 class LoginForm(Form):
51 favor = IntegerField(error={'required': '爱好不能为空'},
52 widget=InputRadio(attr={'class': 'c1'},
53 text_value_list=[
54 {'value': 1, 'text': '男'},
55 {'value': 2, 'text': '女'}, ],
56 checked_value=2
57 )
58 )
59 上述favor字段生成的HTML标签为:
60 <div>
61 <span>
62 <input class='c1' type="radio" name="gender" value="1">
63 </span>
64 <span>男</span>
65 </div>
66 <div>
67 <span>
68 <input class='c1' type="radio" name="gender" value="2" checked='checked'>
69 </span>
70 <span>女</span>
71 </div>
72 """
73
74 InputSingleCheckBox
75 """
76 设置Form对应字段在HTML中生成 input type='checkbox' 标签
77 参数:
78 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1'}
79 """
80
81 InputMultiCheckBox
82 """
83 设置Form对应字段在HTML中生成一系列 input type='checkbox' 标签
84
85 参数:
86 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1'}
87 text_value_list 列表,生成的多个checkbox标签的内容和值,如:[
88 {'value':1, 'text': '篮球'},
89 {'value':2, 'text': '足球'},
90 {'value':3, 'text': '乒乓球'},
91 {'value':4, 'text': '羽毛球'},
92 ]
93 checked_value_list 列表,默认选中的标签对应的value, 如:[1,3]
94 """
95 SingleSelect
96 """
97 设置Form对应字段在HTML中生成 单选select 标签
98
99 参数:
100 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1'}
101 text_value_list 列表,用于指定select标签中的option,如:[
102 {'value':1, 'text': '北京'},
103 {'value':2, 'text': '上海'},
104 {'value':3, 'text': '广州'},
105 {'value':4, 'text': '重庆'},
106 ]
107 selected_value 数字或字符串,默认被选中选项对应的值,如: 3
108 """
109
110 MultiSelect
111 """
112 设置Form对应字段在HTML中生成 多选select 标签
113
114 参数:
115 attr 字典,指定生成标签的属性,如: attr = {'class': 'c1'}
116 text_value_list 列表,用于指定select标签中的option,如:[
117 {'value':1, 'text': '篮球'},
118 {'value':2, 'text': '足球'},
119 {'value':3, 'text': '乒乓球'},
120 {'value':4, 'text': '羽毛球'},
121 ]
122 selected_value_list 列表,默认被选中选项对应的值,如:[2,3,4]
123 """
8、动态初始化默认值
由于Form可以用于生成HTML标签,如果想要在创建标签的同时再为其设置默认值有两种方式:
- 静态,在插件参数中指定
- 动态,调用Form对象的 init_field_value 方法来指定
1 class InitValueForm(Form):
2 username = StringField(error={'required': '用户名不能为空'})
3 age = IntegerField(max_value=500,
4 min_value=0,
5 error={'required': '年龄不能为空',
6 'invalid': '年龄必须为数字',
7 'min_value': '年龄不能小于0',
8 'max_value': '年龄不能大于500'})
9
10 city = IntegerField(error={'required': '年龄不能为空', 'invalid': '年龄必须为数字'},
11 widget=SingleSelect(text_value_list=[{'value': 1, 'text': '上海'},
12 {'value': 2, 'text': '北京'},
13 {'value': 3, 'text': '广州'}])
14 )
15
16 gender = IntegerField(error={'required': '请选择性别',
17 'invalid': '性别必须为数字'},
18 widget=InputRadio(text_value_list=[{'value': 1, 'text': '男', },
19 {'value': 2, 'text': '女', }],
20 checked_value=2))
21
22 protocol = IntegerField(error={'required': '请选择协议', 'invalid': '协议格式错误'},
23 widget=InputSingleCheckBox(attr={'value': 1}))
24
25 favor_int_val = IntegerListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
26 widget=InputMultiCheckBox(text_value_list=[{'value': 1, 'text': '篮球', },
27 {'value': 2, 'text': '足球', },
28 {'value': 3, 'text': '乒乓球', },
29 {'value': 4, 'text': '羽毛球'}, ]))
30
31 favor_str_val = StringListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
32 widget=InputMultiCheckBox(text_value_list=[{'value': '1', 'text': '篮球', },
33 {'value': '2', 'text': '足球', },
34 {'value': '3', 'text': '乒乓球', },
35 {'value': '4', 'text': '羽毛球'}, ]))
36
37 select_str_val = StringListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
38 widget=MultiSelect(text_value_list=[{'value': '1', 'text': '篮球', },
39 {'value': '2', 'text': '足球', },
40 {'value': '3', 'text': '乒乓球', },
41 {'value': '4', 'text': '羽毛球'}, ]))
42
43 select_int_val = IntegerListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
44 widget=MultiSelect(text_value_list=[{'value': 1, 'text': '篮球', },
45 {'value': 2, 'text': '足球', },
46 {'value': 3, 'text': '乒乓球', },
47 {'value': 4, 'text': '羽毛球'}, ]))
1 class InitValueHandler(tornado.web.RequestHandler):
2
3 def get(self, *args, **kwargs):
4 form = InitValueForm(self)
5
6 init_dict = {
7 'username': 'seven',
8 'age': 18,
9 'city': 2,
10 'gender': 2,
11 'protocol': 1,
12 'favor_int_val': [1, 3],
13 'favor_str_val': ['1', '3'],
14 'select_int_val': [1, 3],
15 'select_str_val': ['1', '3']
16
17 }
18
19 # 初始化操作,设置Form类中默认值以及默认选项
20 form.init_field_value(init_dict)
21
22 self.render('init_value.html', form=form)
动态初始值 – 处理请求的Handler(Tornado)
9、更多示例
示例源码下载:猛击这里
a. 基本使用
1 class RegisterForm(Form):
2 username = StringField(max_length=32,
3 min_length=6,
4 error={'required': '用户名不能为空',
5 'min_length': '用户名不能少于6位',
6 'max_length': '用户名不能超过32位'})
7
8 password = StringField(max_length=32,
9 min_length=6,
10 error={'required': '密码不能为空'},
11 widget=InputPassword())
12
13 gender = IntegerField(error={'required': '请选择性别',
14 'invalid': '性别必须为数字'},
15 widget=InputRadio(text_value_list=[{'value': 1, 'text': '男', },
16 {'value': 2, 'text': '女', }],
17 checked_value=2))
18
19 age = IntegerField(max_value=500,
20 min_value=0,
21 error={'required': '年龄不能为空',
22 'invalid': '年龄必须为数字',
23 'min_value': '年龄不能小于0',
24 'max_value': '年龄不能大于500'})
25
26 email = EmailField(error={'required': '邮箱不能为空',
27 'invalid': '邮箱格式错误'})
28
29 city = IntegerField(error={'required': '城市选项不能为空', 'invalid': '城市选项必须为数字'},
30 widget=SingleSelect(text_value_list=[{'value': 1, 'text': '上海'},
31 {'value': 2, 'text': '北京'},
32 {'value': 3, 'text': '广州'}])
33 )
34 protocol = IntegerField(error={'required': '请选择协议', 'invalid': '协议格式错误'},
35 widget=InputSingleCheckBox(attr={'value': 1}))
36
37 memo = StringField(required=False,
38 max_length=150,
39 error={'invalid': '备注格式错误', 'max_length': '备注最大长度为150字'},
40 widget=TextArea())
b. 多选checkbox
1 class MultiCheckBoxForm(Form):
2 favor_str_val = StringListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
3 widget=InputMultiCheckBox(text_value_list=[{'value': '1', 'text': '篮球', },
4 {'value': '2', 'text': '足球', },
5 {'value': '3', 'text': '乒乓球', },
6 {'value': '4', 'text': '羽毛球'}, ]))
7
8 favor_str_val_default = StringListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
9 widget=InputMultiCheckBox(text_value_list=[{'value': '1', 'text': '篮球', },
10 {'value': '2', 'text': '足球', },
11 {'value': '3', 'text': '乒乓球', },
12 {'value': '4', 'text': '羽毛球'}, ],
13 checked_value_list=['1', '4']))
14
15 favor_int_val = IntegerListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
16 widget=InputMultiCheckBox(text_value_list=[{'value': 1, 'text': '篮球', },
17 {'value': 2, 'text': '足球', },
18 {'value': 3, 'text': '乒乓球', },
19 {'value': 4, 'text': '羽毛球'}, ]))
20
21 favor_int_val_default = IntegerListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
22 widget=InputMultiCheckBox(text_value_list=[{'value': 1, 'text': '篮球', },
23 {'value': 2, 'text': '足球', },
24 {'value': 3, 'text': '乒乓球', },
25 {'value': 4, 'text': '羽毛球'}, ],
26 checked_value_list=[2, ]))
c、多选select
1 class MultiSelectForm(Form):
2 select_str_val = StringListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
3 widget=MultiSelect(text_value_list=[{'value': '1', 'text': '篮球', },
4 {'value': '2', 'text': '足球', },
5 {'value': '3', 'text': '乒乓球', },
6 {'value': '4', 'text': '羽毛球'}, ]))
7
8 select_str_val_default = StringListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
9 widget=MultiSelect(text_value_list=[{'value': '1', 'text': '篮球', },
10 {'value': '2', 'text': '足球', },
11 {'value': '3', 'text': '乒乓球', },
12 {'value': '4', 'text': '羽毛球'}, ],
13 selected_value_list=['1', '3']))
14
15 select_int_val = IntegerListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
16 widget=MultiSelect(text_value_list=[{'value': 1, 'text': '篮球', },
17 {'value': 2, 'text': '足球', },
18 {'value': 3, 'text': '乒乓球', },
19 {'value': 4, 'text': '羽毛球'}, ]))
20
21 select_int_val_default = IntegerListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
22 widget=MultiSelect(text_value_list=[{'value': 1, 'text': '篮球', },
23 {'value': 2, 'text': '足球', },
24 {'value': 3, 'text': '乒乓球', },
25 {'value': 4, 'text': '羽毛球'}, ],
26 selected_value_list=[2]))
d. 动态select选项
1 class DynamicSelectForm(Form):
2 city = IntegerField(error={'required': '年龄不能为空', 'invalid': '年龄必须为数字'},
3 widget=SingleSelect(text_value_list=[{'value': 1, 'text': '上海'},
4 {'value': 2, 'text': '北京'},
5 {'value': 3, 'text': '广州'}])
6 )
7
8 multi_favor = IntegerListField(error={'required': '请选择爱好', 'invalid': '选择爱好格式错误'},
9 widget=MultiSelect(text_value_list=[{'value': 1, 'text': '篮球', },
10 {'value': 2, 'text': '足球', },
11 {'value': 3, 'text': '乒乓球', },
12 {'value': 4, 'text': '羽毛球'}, ]))
13
14 def __init__(self, *args, **kwargs):
15 super(DynamicSelectForm, self).__init__(*args, **kwargs)
16
17 # 获取数据库中的最新数据并显示在页面上(每次创建对象都执行一次数据库操作来获取最新数据)
18 self.city.widget.text_value_list = [{'value': 1, 'text': '上海'},
19 {'value': 2, 'text': '北京'},
20 {'value': 3, 'text': '南京'},
21 {'value': 4, 'text': '广州'}]
22
23 self.multi_favor.widget.text_value_list = [{'value': 1, 'text': '篮球'},
24 {'value': 2, 'text': '足球'},
25 {'value': 3, 'text': '乒乓球'},
26 {'value': 4, 'text': '羽毛球'},
27 {'value': 5, 'text': '玻璃球'}]