├── .idea
├── .name
├── Tyrion.iml
├── dictionaries
│ └── wupeiqi.xml
├── encodings.xml
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── scopes
│ └── scope_settings.xml
├── vcs.xml
└── workspace.xml
├── LICENSE
├── MANIFEST.in
├── PyTyrion.egg-info
├── PKG-INFO
├── SOURCES.txt
├── dependency_links.txt
└── top_level.txt
├── README.rst
├── Tyrion
├── Fields.py
├── Forms.py
├── Framework.py
├── Widget.py
├── __init__.py
└── __pycache__
│ ├── Fields.cpython-35.pyc
│ ├── Forms.cpython-35.pyc
│ ├── Framework.cpython-35.pyc
│ ├── Widget.cpython-35.pyc
│ └── __init__.cpython-35.pyc
├── dist
└── PyTyrion-1.0.1.tar.gz
└── setup.py
/.idea/.name:
--------------------------------------------------------------------------------
1 | Tyrion
--------------------------------------------------------------------------------
/.idea/Tyrion.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/dictionaries/wupeiqi.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
176 |
177 |
178 | true
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 | true
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 | 1474858214961
597 |
598 | 1474858214961
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 WuPeiqi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | # Include the readme file
2 | include READEME.rst
3 |
--------------------------------------------------------------------------------
/PyTyrion.egg-info/PKG-INFO:
--------------------------------------------------------------------------------
1 | Metadata-Version: 1.1
2 | Name: PyTyrion
3 | Version: 1.0.1
4 | Summary: 支持Tornado、Django、Bottle、Flask的Web表单验证
5 | Home-page: https://github.com/WuPeiqi/Tyrion
6 | Author: wupeiqi
7 | Author-email: wupeiq@live.com
8 | License: MIT
9 | Description: Python Web框架表单验证组件 - Tyrion
10 | =======================
11 |
12 | Tyrion是一个基于Python实现的支持多个WEB框架的Form表单验证组件,其完美的支持Tornado、Django、Flask、Bottle Web框架。
13 | Tyrion主要有两大重要动能:
14 |
15 | - 表单验证
16 |
17 | - 生成HTML标签
18 |
19 | - 保留上次提交内容
20 |
21 | 对于表单验证,告别书写重复的正则表达式对用户提交的数据进行验证的工作,从此解放双手,跟着我左手右手一个慢动作...
22 |
23 | 对于生成HTML标签,不在人工书写html标签,让Tyrion帮你自动创建...
24 |
25 | 对于保留上次提交内容,由于默认表单提交后页面刷新,原来输入的内容会清空,Tyrion可以保留上次提交内容。
26 |
27 | 下载安装
28 | :::::::::
29 | ::
30 |
31 | pip3 install PyTyrion
32 |
33 | 中文文档
34 | :::::::::
35 | http://www.cnblogs.com/wupeiqi/p/5938916.html
36 |
37 | Keywords: web form python tornado django bottle flask
38 | Platform: UNKNOWN
39 | Classifier: Development Status :: 4 - Beta
40 | Classifier: Intended Audience :: Developers
41 | Classifier: Topic :: Software Development :: Build Tools
42 | Classifier: License :: OSI Approved :: MIT License
43 | Classifier: Programming Language :: Python :: 2
44 | Classifier: Programming Language :: Python :: 2.6
45 | Classifier: Programming Language :: Python :: 2.7
46 | Classifier: Programming Language :: Python :: 3
47 | Classifier: Programming Language :: Python :: 3.3
48 | Classifier: Programming Language :: Python :: 3.4
49 | Classifier: Programming Language :: Python :: 3.5
50 |
--------------------------------------------------------------------------------
/PyTyrion.egg-info/SOURCES.txt:
--------------------------------------------------------------------------------
1 | MANIFEST.in
2 | README.rst
3 | setup.py
4 | PyTyrion.egg-info/.DS_Store
5 | PyTyrion.egg-info/PKG-INFO
6 | PyTyrion.egg-info/SOURCES.txt
7 | PyTyrion.egg-info/dependency_links.txt
8 | PyTyrion.egg-info/top_level.txt
9 | Tyrion/Fields.py
10 | Tyrion/Forms.py
11 | Tyrion/Framework.py
12 | Tyrion/Widget.py
13 | Tyrion/__init__.py
--------------------------------------------------------------------------------
/PyTyrion.egg-info/dependency_links.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/PyTyrion.egg-info/top_level.txt:
--------------------------------------------------------------------------------
1 | Tyrion
2 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Python Web框架表单验证组件 - Tyrion
2 | =======================
3 |
4 | Tyrion是一个基于Python实现的支持多个WEB框架的Form表单验证组件,其完美的支持Tornado、Django、Flask、Bottle Web框架。
5 | Tyrion主要有两大重要动能:
6 |
7 | - 表单验证
8 |
9 | - 生成HTML标签
10 |
11 | - 保留上次提交内容
12 |
13 | 对于表单验证,告别书写重复的正则表达式对用户提交的数据进行验证的工作,从此解放双手,跟着我左手右手一个慢动作...
14 |
15 | 对于生成HTML标签,不在人工书写html标签,让Tyrion帮你自动创建...
16 |
17 | 对于保留上次提交内容,由于默认表单提交后页面刷新,原来输入的内容会清空,Tyrion可以保留上次提交内容。
18 |
19 | 下载安装
20 | :::::::::
21 | ::
22 |
23 | pip3 install PyTyrion
24 |
25 | 中文文档
26 | :::::::::
27 | http://www.cnblogs.com/wupeiqi/p/5938916.html
28 |
--------------------------------------------------------------------------------
/Tyrion/Fields.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | import re
4 | from Tyrion import Widget
5 | from Tyrion.Framework import FrameworkFactory
6 |
7 |
8 | class Field(object):
9 | """
10 | 所有Form字段的基类
11 | """
12 |
13 | def __init__(self, widget):
14 | self.status = False
15 | self.name = None
16 | self.value = None
17 | self.error = None
18 | self.widget = widget
19 |
20 | def valid(self, handler):
21 | """
22 | 字段必须实现该方法,用于从请求中获取用户输入的值并和规则进行比较
23 | :param handler: Tornado处理请求的XXXHandler对象
24 | :return:
25 | """
26 | raise NotImplementedError('your class %s must implement valid method' % self.__class__)
27 |
28 | def __str__(self):
29 |
30 | if self.value == None:
31 | return str(self.widget)
32 |
33 | if isinstance(self.widget, Widget.SingleSelect):
34 | self.widget.selected_value = self.value
35 | elif isinstance(self.widget, Widget.MultiSelect):
36 | self.widget.selected_value_list = self.value
37 | elif isinstance(self.widget, Widget.InputSingleCheckBox):
38 | self.widget.attr['checked'] = 'checked'
39 | elif isinstance(self.widget, Widget.InputMultiCheckBox):
40 | self.widget.checked_value_list = self.value
41 | elif isinstance(self.widget, Widget.InputRadio):
42 | self.widget.checked_value = self.value
43 | elif isinstance(self.widget, Widget.TextArea):
44 | self.widget.value = self.value
45 | else:
46 | self.widget.attr['value'] = self.value
47 | return str(self.widget)
48 |
49 | def set_value(self, value):
50 | self.value = value
51 |
52 |
53 | class StringField(Field):
54 | """
55 | 字符串类字段
56 | """
57 | REGULAR = "^.*$"
58 | DEFAULT_WIDGET = Widget.InputText
59 |
60 | def __init__(self, max_length=None, min_length=None, error=None, required=True, widget=None):
61 | """
62 | :param error: 自定义错误信息
63 | 如:{
64 | 'required': '值为空时的错误提示',
65 | 'invalid': '格式错误时的错误提示',
66 | 'max_length': '最大长度为10',
67 | 'min_length': '最小长度为1',
68 | }
69 | :param required: 是否必须
70 | :param widget: 指定插件,用于生成HTML标签(默认生成Input标签)
71 | :return:
72 | """
73 | self.custom_error_dict = {}
74 | if error:
75 | self.custom_error_dict.update(error)
76 |
77 | self.required = required
78 | self.max_length = max_length
79 | self.min_length = min_length
80 |
81 | widget = widget if widget else self.DEFAULT_WIDGET()
82 |
83 | super(StringField, self).__init__(widget)
84 |
85 | def valid(self, handler):
86 | """
87 | 从请求中获取用户输入的值并和规则进行比较
88 | :param handler: Tornado处理请求的XXXHandler对象
89 | :return:
90 | """
91 | input_value = FrameworkFactory.get_framework().get_argument(handler, self.name, None)
92 | # input_value = handler.get_argument(self.name, None)
93 |
94 | self.value = input_value
95 |
96 | if not input_value:
97 | if not self.required:
98 | self.status = True
99 | return
100 |
101 | if self.custom_error_dict.get('required', None):
102 | self.error = self.custom_error_dict['required']
103 | else:
104 | self.error = "%s is required" % self.name
105 | return
106 |
107 | ret = re.match(self.REGULAR, input_value)
108 | if not ret:
109 | if self.custom_error_dict.get('invalid', None):
110 | self.error = self.custom_error_dict['invalid']
111 | else:
112 | self.error = "%s is invalid" % self.name
113 | return
114 |
115 | if self.max_length:
116 | if len(input_value) > self.max_length:
117 | if self.custom_error_dict.get('max_length', None):
118 | self.error = self.custom_error_dict['max_length']
119 | else:
120 | self.error = "%s max length is %s" % (self.name, self.max_length)
121 | return
122 |
123 | if self.min_length:
124 |
125 | if len(input_value) < self.min_length:
126 | if self.custom_error_dict.get('min_length', None):
127 | self.error = self.custom_error_dict['min_length']
128 | else:
129 | self.error = "%s min length is %s" % (self.name, self.min_length)
130 | return
131 |
132 | self.status = True
133 |
134 |
135 | class EmailField(Field):
136 | """
137 | 字符串类字段
138 | """
139 | REGULAR = "^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"
140 | DEFAULT_WIDGET = Widget.InputText
141 |
142 | def __init__(self, max_length=None, min_length=None, error=None, required=True, widget=None):
143 | """
144 | :param error: 自定义错误信息
145 | 如:{
146 | 'required': '值为空时的错误提示',
147 | 'invalid': '格式错误时的错误提示',
148 | 'max_length': '最大长度为10',
149 | 'min_length': '最小长度为1',
150 | }
151 | :param required: 是否必须
152 | :param widget: 指定插件,用于生成HTML标签(默认生成Input标签)
153 | :return:
154 | """
155 | self.custom_error_dict = {}
156 | if error:
157 | self.custom_error_dict.update(error)
158 |
159 | self.required = required
160 | self.max_length = max_length
161 | self.min_length = min_length
162 |
163 | widget = widget if widget else self.DEFAULT_WIDGET()
164 |
165 | super(EmailField, self).__init__(widget)
166 |
167 | def valid(self, handler):
168 | """
169 | 从请求中获取用户输入的值并和规则进行比较
170 | :param handler: Tornado处理请求的XXXHandler对象
171 | :return:
172 | """
173 |
174 | input_value = FrameworkFactory.get_framework().get_argument(handler, self.name, None)
175 | # input_value = handler.get_argument(self.name, None)
176 |
177 | self.value = input_value
178 | if not input_value:
179 | if not self.required:
180 | self.status = True
181 | return
182 | if self.custom_error_dict.get('required', None):
183 | self.error = self.custom_error_dict['required']
184 | else:
185 | self.error = "%s is required" % self.name
186 | return
187 |
188 | ret = re.match(self.REGULAR, input_value)
189 | if not ret:
190 | if self.custom_error_dict.get('invalid', None):
191 | self.error = self.custom_error_dict['invalid']
192 | else:
193 | self.error = "%s is invalid" % self.name
194 | return
195 |
196 | if self.max_length:
197 | if len(input_value) > self.max_length:
198 | if self.custom_error_dict.get('max_length', None):
199 | self.error = self.custom_error_dict['max_length']
200 | else:
201 | self.error = "%s max length is %s" % (self.name, self.max_length)
202 | return
203 |
204 | if self.min_length:
205 | if len(input_value) < self.max_length:
206 | if self.custom_error_dict.get('min_length', None):
207 | self.error = self.custom_error_dict['min_length']
208 | else:
209 | self.error = "%s min length is %s" % (self.name, self.min_length)
210 | return
211 |
212 | self.status = True
213 |
214 |
215 | class IPField(Field):
216 | """
217 | 字符串类字段
218 | """
219 | REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
220 | DEFAULT_WIDGET = Widget.InputText
221 |
222 | def __init__(self, max_length=None, min_length=None, error=None, required=True, widget=None):
223 | """
224 | :param error: 自定义错误信息
225 | 如:{
226 | 'required': '值为空时的错误提示',
227 | 'invalid': '格式错误时的错误提示',
228 | 'max_length': '最大长度为10',
229 | 'min_length': '最小长度为1',
230 | }
231 | :param required: 是否必须
232 | :param widget: 指定插件,用于生成HTML标签(默认生成Input标签)
233 | :return:
234 | """
235 | self.custom_error_dict = {}
236 | if error:
237 | self.custom_error_dict.update(error)
238 |
239 | self.required = required
240 | self.max_length = max_length
241 | self.min_length = min_length
242 |
243 | widget = widget if widget else self.DEFAULT_WIDGET()
244 |
245 | super(IPField, self).__init__(widget)
246 |
247 | def valid(self, handler):
248 | """
249 | 从请求中获取用户输入的值并和规则进行比较
250 | :param handler: Tornado处理请求的XXXHandler对象
251 | :return:
252 | """
253 | input_value = FrameworkFactory.get_framework().get_argument(handler, self.name, None)
254 | # input_value = handler.get_argument(self.name, None)
255 |
256 | self.value = input_value
257 | if not input_value:
258 | if not self.required:
259 | self.status = True
260 | return
261 |
262 | if self.custom_error_dict.get('required', None):
263 | self.error = self.custom_error_dict['required']
264 | else:
265 | self.error = "%s is required" % self.name
266 | return
267 |
268 | ret = re.match(self.REGULAR, input_value)
269 | if not ret:
270 | if self.custom_error_dict.get('invalid', None):
271 | self.error = self.custom_error_dict['invalid']
272 | else:
273 | self.error = "%s is invalid" % self.name
274 | return
275 |
276 | if self.max_length:
277 | if len(input_value) > self.max_length:
278 | if self.custom_error_dict.get('max_length', None):
279 | self.error = self.custom_error_dict['max_length']
280 | else:
281 | self.error = "%s max length is %s" % (self.name, self.max_length)
282 | return
283 |
284 | if self.min_length:
285 | if len(input_value) < self.max_length:
286 | if self.custom_error_dict.get('min_length', None):
287 | self.error = self.custom_error_dict['min_length']
288 | else:
289 | self.error = "%s min length is %s" % (self.name, self.min_length)
290 | return
291 |
292 | self.status = True
293 |
294 |
295 | class IntegerField(Field):
296 | """
297 | 字符串类字段
298 | """
299 | REGULAR = "^\d+$"
300 | DEFAULT_WIDGET = Widget.InputText
301 |
302 | def __init__(self, max_value=None, min_value=None, error=None, required=True, widget=None):
303 | """
304 | :param error: 自定义错误信息
305 | 如:{
306 | 'required': '值为空时的错误提示',
307 | 'invalid': '格式错误时的错误提示',
308 | 'max_value': '最大值为10',
309 | 'max_value': '最小值度为1',
310 | }
311 | :param required: 是否必须
312 | :param widget: 指定插件,用于生成HTML标签(默认生成Input标签)
313 | :return:
314 | """
315 | self.custom_error_dict = {}
316 | if error:
317 | self.custom_error_dict.update(error)
318 |
319 | self.required = required
320 | self.max_value = max_value
321 | self.min_value = min_value
322 |
323 | widget = widget if widget else self.DEFAULT_WIDGET()
324 |
325 | super(IntegerField, self).__init__(widget)
326 |
327 | def valid(self, handler):
328 | """
329 | 从请求中获取用户输入的值并和规则进行比较
330 | :param handler: Tornado处理请求的XXXHandler对象
331 | :return:
332 | """
333 | input_value = FrameworkFactory.get_framework().get_argument(handler, self.name, None)
334 | # input_value = handler.get_argument(self.name, None)
335 |
336 | self.value = input_value
337 |
338 | if not input_value:
339 | if not self.required:
340 | self.status = True
341 | return
342 |
343 | if self.custom_error_dict.get('required', None):
344 | self.error = self.custom_error_dict['required']
345 | else:
346 | self.error = "%s is required" % self.name
347 | return
348 |
349 | ret = re.match(self.REGULAR, input_value)
350 | if not ret:
351 | if self.custom_error_dict.get('invalid', None):
352 | self.error = self.custom_error_dict['invalid']
353 | else:
354 | self.error = "%s is invalid" % self.name
355 | return
356 |
357 | input_value = int(input_value)
358 | self.value = input_value
359 |
360 | if self.max_value:
361 | if input_value > self.max_value:
362 | if self.custom_error_dict.get('max_value', None):
363 | self.error = self.custom_error_dict['max_value']
364 | else:
365 | self.error = "%s max value is %s" % (self.name, self.max_value)
366 | return
367 |
368 | if self.min_value:
369 | if input_value < self.min_value:
370 | if self.custom_error_dict.get('min_value', None):
371 | self.error = self.custom_error_dict['min_value']
372 | else:
373 | self.error = "%s min value is %s" % (self.name, self.min_value)
374 | return
375 |
376 | self.status = True
377 |
378 |
379 | class FloatField(Field):
380 | """
381 | 字符串类字段
382 | """
383 | REGULAR = "^\d+(\.\d{1,2})?$"
384 | DEFAULT_WIDGET = Widget.InputText
385 |
386 | def __init__(self, max_value=None, min_value=None, error=None, required=True, widget=None):
387 | """
388 | :param error: 自定义错误信息
389 | 如:{
390 | 'required': '值为空时的错误提示',
391 | 'invalid': '格式错误时的错误提示',
392 | 'max_value': '最大值为10',
393 | 'min_value': '最小值度为1',
394 | }
395 | :param required: 是否必须
396 | :param widget: 指定插件,用于生成HTML标签(默认生成Input标签)
397 | :return:
398 | """
399 | self.custom_error_dict = {}
400 | if error:
401 | self.custom_error_dict.update(error)
402 |
403 | self.required = required
404 | self.max_value = max_value
405 | self.min_value = min_value
406 |
407 | widget = widget if widget else self.DEFAULT_WIDGET()
408 |
409 | super(FloatField, self).__init__(widget)
410 |
411 | def valid(self, handler):
412 | """
413 | 从请求中获取用户输入的值并和规则进行比较
414 | :param handler: Tornado处理请求的XXXHandler对象
415 | :return:
416 | """
417 | input_value = FrameworkFactory.get_framework().get_argument(handler, self.name, None)
418 | # input_value = handler.get_argument(self.name, None)
419 |
420 | self.value = input_value
421 | if not input_value:
422 | if not self.required:
423 | self.status = True
424 | return
425 |
426 | if self.custom_error_dict.get('required', None):
427 | self.error = self.custom_error_dict['required']
428 | else:
429 | self.error = "%s is required" % self.name
430 | return
431 |
432 | ret = re.match(self.REGULAR, input_value)
433 | if not ret:
434 | if self.custom_error_dict.get('invalid', None):
435 | self.error = self.custom_error_dict['invalid']
436 | else:
437 | self.error = "%s is invalid" % self.name
438 | return
439 |
440 | input_value = float(input_value)
441 | self.value = input_value
442 |
443 | if self.max_value:
444 | if input_value > self.max_value:
445 | if self.custom_error_dict.get('max_value', None):
446 | self.error = self.custom_error_dict['max_value']
447 | else:
448 | self.error = "%s max value is %s" % (self.name, self.max_value)
449 | return
450 |
451 | if self.min_value:
452 | if input_value < self.min_value:
453 | if self.custom_error_dict.get('min_value', None):
454 | self.error = self.custom_error_dict['min_value']
455 | else:
456 | self.error = "%s min value is %s" % (self.name, self.min_value)
457 | return
458 |
459 | self.status = True
460 |
461 |
462 | class StringListField(Field):
463 | """
464 | 字符串类字段
465 | """
466 | REGULAR = "^.*$"
467 | DEFAULT_WIDGET = Widget.InputMultiCheckBox
468 |
469 | def __init__(self, ele_max_length=None, ele_min_length=None, error=None, required=True, widget=None):
470 | """
471 | :param error: 自定义错误信息
472 | 如:{
473 | 'required': '值为空时的错误提示',
474 | 'element': '列表中的元素必须是字符串',
475 | 'ele_max_length': '最大长度为10',
476 | 'ele_min_length': '最小长度为1',
477 | }
478 | :param required: 是否必须
479 | :param widget: 指定插件,用于生成HTML标签(默认生成Input标签)
480 | :return:
481 | """
482 | self.custom_error_dict = {}
483 | if error:
484 | self.custom_error_dict.update(error)
485 |
486 | self.required = required
487 | self.ele_max_length = ele_max_length
488 | self.ele_min_length = ele_min_length
489 |
490 | widget = widget if widget else self.DEFAULT_WIDGET()
491 |
492 | super(StringListField, self).__init__(widget)
493 |
494 | def valid(self, handler):
495 | """
496 | 从请求中获取用户输入的值并和规则进行比较
497 | :param handler: Tornado处理请求的XXXHandler对象
498 | :return:
499 | """
500 | input_value = FrameworkFactory.get_framework().get_arguments(handler, self.name, [])
501 | # input_value = handler.get_arguments(self.name)
502 |
503 | self.value = input_value
504 |
505 | if not input_value:
506 | if not self.required:
507 | self.status = True
508 | return
509 |
510 | if self.custom_error_dict.get('required', None):
511 | self.error = self.custom_error_dict['required']
512 | else:
513 | self.error = "%s is required" % self.name
514 | return
515 |
516 | for value in input_value:
517 | ret = re.match(self.REGULAR, value)
518 | if not ret:
519 | if self.custom_error_dict.get('element', None):
520 | self.error = self.custom_error_dict['element']
521 | else:
522 | self.error = "element %s is invalid" % self.name
523 | return
524 |
525 | if self.ele_max_length:
526 | if len(value) > self.ele_max_length:
527 | if self.custom_error_dict.get('ele_max_length', None):
528 | self.error = self.custom_error_dict['ele_max_length']
529 | else:
530 | self.error = "element %s max length is %s" % (self.name, self.ele_max_length)
531 | return
532 |
533 | if self.ele_min_length:
534 |
535 | if len(value) < self.ele_min_length:
536 | if self.custom_error_dict.get('ele_min_length', None):
537 | self.error = self.custom_error_dict['ele_min_length']
538 | else:
539 | self.error = "element %s min length is %s" % (self.name, self.ele_min_length)
540 | return
541 |
542 | self.status = True
543 |
544 |
545 | class IntegerListField(Field):
546 | """
547 | 字符串类字段
548 | """
549 | REGULAR = "^\d+$"
550 | DEFAULT_WIDGET = Widget.InputMultiCheckBox
551 |
552 | def __init__(self, ele_max_value=None, ele_min_value=None, error=None, required=True, widget=None):
553 | """
554 | :param error: 自定义错误信息
555 | 如:{
556 | 'required': '值为空时的错误提示',
557 | 'element': '列表中的元素必须是数字',
558 | 'ele_max_value': '最大值为x',
559 | 'ele_min_value': '最小值为x',
560 | }
561 | :param required: 是否必须
562 | :param widget: 指定插件,用于生成HTML标签(默认生成Input标签)
563 | :return:
564 | """
565 | self.custom_error_dict = {}
566 | if error:
567 | self.custom_error_dict.update(error)
568 |
569 | self.required = required
570 | self.ele_max_value = ele_max_value
571 | self.ele_min_value = ele_min_value
572 |
573 | widget = widget if widget else self.DEFAULT_WIDGET()
574 |
575 | super(IntegerListField, self).__init__(widget)
576 |
577 | def valid(self, handler):
578 | """
579 | 从请求中获取用户输入的值并和规则进行比较
580 | :param handler: Tornado处理请求的XXXHandler对象
581 | :return:
582 | """
583 | input_value = FrameworkFactory.get_framework().get_arguments(handler, self.name, [])
584 | # input_value = handler.get_arguments(self.name)
585 | self.value = input_value
586 |
587 | if not input_value:
588 | if not self.required:
589 | self.status = True
590 | return
591 |
592 | if self.custom_error_dict.get('required', None):
593 | self.error = self.custom_error_dict['required']
594 | else:
595 | self.error = "%s is required" % self.name
596 | return
597 |
598 | success_value_list = []
599 | for value in input_value:
600 | ret = re.match(self.REGULAR, value)
601 | if not ret:
602 | if self.custom_error_dict.get('element', None):
603 | self.error = self.custom_error_dict['element']
604 | else:
605 | self.error = "element %s is invalid" % self.name
606 | return
607 | value = int(value)
608 | success_value_list.append(value)
609 |
610 | if self.ele_max_value:
611 | if value > self.ele_max_value:
612 | if self.custom_error_dict.get('ele_max_value', None):
613 | self.error = self.custom_error_dict['ele_max_value']
614 | else:
615 | self.error = "element %s max value is %s" % (self.name, self.ele_max_value)
616 | return
617 |
618 | if self.ele_min_value:
619 |
620 | if value < self.ele_min_value:
621 | if self.custom_error_dict.get('ele_min_value', None):
622 | self.error = self.custom_error_dict['ele_min_value']
623 | else:
624 | self.error = "element %s min value is %s" % (self.name, self.ele_min_value)
625 | return
626 |
627 | self.value = success_value_list
628 | self.status = True
--------------------------------------------------------------------------------
/Tyrion/Forms.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | import copy
4 | from Tyrion.Fields import Field
5 |
6 |
7 | class Form(object):
8 | def __init__(self, handler=None):
9 | """
10 |
11 | :param handler: Tornado请求中的XXXHandler对象
12 | :return:
13 | """
14 | self.handler = handler
15 | self.FiledDict = {}
16 | self.value_dict = {}
17 | self.error_dict = {}
18 | self.valid_status = True
19 |
20 | self.initialize()
21 |
22 | def initialize(self):
23 | """
24 | 初始化,将派生类Form中的静态字段拷贝到字段FiledDict中,并为字段对应的Html插件设置id和name属性
25 | :return:
26 | """
27 | for k, v in self.__class__.__dict__.items():
28 | if isinstance(v, Field):
29 | field = copy.deepcopy(v)
30 | field.name = k
31 | field.widget.attr['name'] = k
32 | """
33 | if 'id' not in field.widget.attr:
34 | field.widget.attr['id'] = '%s_%s' % ('id', k)
35 | """
36 | self.FiledDict[k] = field
37 | self.__dict__.update(self.FiledDict)
38 |
39 | def is_valid(self):
40 | """
41 | 验证用户输入和规则是否匹配
42 | :return:
43 | """
44 | for k, v in self.FiledDict.items():
45 | v.valid(self.handler)
46 | if v.status:
47 | self.value_dict[k] = v.value
48 | else:
49 | self.error_dict[k] = v.error
50 | self.valid_status = False
51 |
52 | return self.valid_status
53 |
54 | def init_field_value(self, value_dict):
55 | """
56 | 设置默认 显示的值 或 选中的值
57 | :param value_dict:
58 | :return:
59 | """
60 | for k, v in self.FiledDict.items():
61 | v.set_value(value_dict.get(k, None))
62 |
63 |
--------------------------------------------------------------------------------
/Tyrion/Framework.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 |
4 |
5 | class FrameworkFactory(object):
6 | __framework = None
7 |
8 | @staticmethod
9 | def set_framework(framework):
10 | FrameworkFactory.__framework = framework
11 |
12 | @staticmethod
13 | def get_framework():
14 | return FrameworkFactory.__framework
15 |
16 |
17 | class BaseFramework(object):
18 | def get_argument(self, request, name, default=None):
19 | raise NotImplementedError('class %s must implement get_argument method' % self.__class__)
20 |
21 | def get_arguments(self, request, name, default=None):
22 | raise NotImplementedError('class %s must implement get_arguments method' % self.__class__)
23 |
24 |
25 | class Tornado(BaseFramework):
26 | def get_argument(self, request, name, default=None):
27 | """
28 | 从请求中获取用户输入或选择的单值
29 | PS:
30 | request.get_argument('username',None) 表示从GET和POST等中获取请求
31 | request.get_query_argument('username',None) 表示从GET中获取请求
32 | request.get_body_argument('username',None) 表示从POST等中获取请求
33 | :param request: Tornado请求中的的 xxxHandler对象,即:self;如:self.get_argument('username',None)
34 | :param name:
35 | :param default:
36 | :return:
37 | """
38 | return request.get_argument(name, default)
39 |
40 | def get_arguments(self, request, name, default=None):
41 | """
42 | 从请求中获取用户输入或选择的多个值(列表类型)
43 | PS:
44 | request.get_argument('username',None) 表示从GET和POST等中获取请求
45 | request.get_query_argument('username',None) 表示从GET中获取请求
46 | request.get_body_argument('username',None) 表示从POST等中获取请求
47 | :param request: Tornado请求中的的 xxxHandler对象,即:self;如:self.get_argument('username',None)
48 | :param name:
49 | :param default:
50 | :return:
51 | """
52 | value = request.get_arguments(name)
53 | if value:
54 | return value
55 | return default
56 |
57 |
58 | class Django(BaseFramework):
59 | def get_argument(self, request, name, default=None):
60 | """
61 | :param request: Django中request参数
62 | :param name:
63 | :param default:
64 | :return:
65 | """
66 | post = request.POST.get(name)
67 | if post:
68 | return post
69 | get = request.GET.get(name)
70 | if get:
71 | return get
72 | return default
73 |
74 | def get_arguments(self, request, name, default=None):
75 | """
76 |
77 | :param request:
78 | :param name:
79 | :param default:
80 | :return:
81 | """
82 | post = request.POST.getlist(name)
83 | if post:
84 | return post
85 | get = request.GET.getlist(name)
86 | if get:
87 | return get
88 | return default
89 |
90 |
91 | class Flask(BaseFramework):
92 | def get_argument(self, request, name, default=None):
93 | """
94 | 从请求中获取用户输入或选择的单值
95 | PS:
96 | request.values 表示从GET和POST中获取请求
97 | request.form 表示从POST中获取请求
98 | request.arg 表示从GET中获取请求
99 | :param request: Flask框架中封装了用户请求的request,即:from flask import request
100 | :param name:
101 | :param default:
102 | :return:
103 | """
104 | return request.values.get(name, default)
105 |
106 | def get_arguments(self, request, name, default=None):
107 | """
108 | 从请求中获取用户输入或选择的多个值
109 | PS:
110 | request.values 表示从GET和POST中获取请求
111 | request.form 表示从POST中获取请求
112 | request.arg 表示从GET中获取请求
113 | :param request: Flask框架中封装了用户请求的request,即:from flask import request
114 | :param name:
115 | :param default:
116 | :return:
117 | """
118 | get_post = request.values.getlist(name)
119 | if get_post:
120 | return get_post
121 | return default
122 |
123 |
124 | class Bottle(BaseFramework):
125 | def get_argument(self, request, name, default=None):
126 | """
127 | 从请求中获取用户输入或选择的单值
128 | PS:
129 | request.params 表示从GET和POST中获取请求
130 | request.forms 表示从POST中获取请求
131 | request.query 表示从GET中获取请求
132 | :param request: Bottle框架中封装了用户请求的request,即:from bottle import request
133 | :param name:
134 | :param default:
135 | :return:
136 | """
137 | get_post = request.params.get(name, default)
138 | return get_post
139 |
140 | def get_arguments(self, request, name, default=None):
141 | """
142 | 从请求中获取用户输入或选择的多个值
143 | PS:
144 | request.params 表示从GET和POST中获取请求
145 | request.forms 表示从POST中获取请求
146 | request.query 表示从GET中获取请求
147 | :param request: Bottle框架中封装了用户请求的request,即:from bottle import request
148 | :param name:
149 | :param default:
150 | :return:
151 | """
152 | get_post = request.params.getall(name)
153 | if not get_post:
154 | return default
155 | return get_post
156 |
--------------------------------------------------------------------------------
/Tyrion/Widget.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 |
4 |
5 | class Input(object):
6 | def __init__(self, attr=None):
7 | """
8 | :param attr: 生成的HTML属性,如:{'id': '123'}
9 | :return:
10 | """
11 | self.attr = attr if attr else {}
12 |
13 | def __str__(self):
14 | """
15 | 使用对象时返回的字符串
16 | :return:
17 | """
18 | t = ""
19 | attr_list = []
20 | for k, v in self.attr.items():
21 | temp = "%s='%s' " % (k, v,)
22 | attr_list.append(temp)
23 | tag = t % (''.join(attr_list))
24 | return tag
25 |
26 |
27 | class InputText(Input):
28 | def __init__(self, attr=None):
29 | attr_dict = {'type': 'text'}
30 | if attr:
31 | attr_dict.update(attr)
32 | super(InputText, self).__init__(attr_dict)
33 |
34 |
35 | class InputEmail(Input):
36 | def __init__(self, attr=None):
37 | attr_dict = {'type': 'email'}
38 | if attr:
39 | attr_dict.update(attr)
40 | super(InputEmail, self).__init__(attr_dict)
41 |
42 |
43 | class InputPassword(Input):
44 | def __init__(self, attr=None):
45 | attr_dict = {'type': 'password'}
46 | if attr:
47 | attr_dict.update(attr)
48 | super(InputPassword, self).__init__(attr_dict)
49 |
50 |
51 | class InputSingleCheckBox(Input):
52 | def __init__(self, attr=None):
53 | attr_dict = {'type': 'checkbox'}
54 | if attr:
55 | attr_dict.update(attr)
56 | super(InputSingleCheckBox, self).__init__(attr_dict)
57 |
58 | def __str__(self):
59 | """
60 | 使用对象时返回的字符串
61 | :return:
62 | """
63 | t = ""
64 | attr_list = []
65 | for k, v in self.attr.items():
66 | temp = "%s='%s' " % (k, v,)
67 | attr_list.append(temp)
68 | tag = t % (''.join(attr_list))
69 | return tag
70 |
71 |
72 | class InputMultiCheckBox(object):
73 | def __init__(self, attr=None, text_value_list=None, checked_value_list=None):
74 | """
75 | :param attr: 生成的HTML属性,如:{'id': '123'}
76 | :param text_value_list: 生成CheckBox的value和内容,如:
77 | [
78 | {'value':1, 'text': '篮球'},
79 | {'value':2, 'text': '足球'},
80 | {'value':3, 'text': '乒乓球'},
81 | {'value':4, 'text': '羽毛球'},
82 | ]
83 | :param checked_value_list: 被选中的checked_value_list,如:[2,3]
84 | :return:
85 | """
86 | attr_dict = {'type': 'checkbox'}
87 | if attr:
88 | attr_dict.update(attr)
89 | self.attr = attr_dict
90 |
91 | self.text_value_list = text_value_list if text_value_list else []
92 | self.checked_value_list = checked_value_list if checked_value_list else []
93 |
94 | def __str__(self):
95 | """
96 | 使用对象时返回的字符串
97 | :return:
98 | """
99 | tag_list = []
100 | for item in self.text_value_list:
101 | a = "
%s%s
"
102 | b = ""
103 | attr_list = []
104 | for k, v in self.attr.items():
105 | temp = "%s='%s' " % (k, v,)
106 | attr_list.append(temp)
107 | attr_list.append("%s='%s' " % ('value', item['value']))
108 | if item['value'] in self.checked_value_list:
109 | attr_list.append("checked='checked' ")
110 | input_tag = b % (''.join(attr_list))
111 | c = a % (input_tag, item['text'], )
112 | tag_list.append(c)
113 | return ''.join(tag_list)
114 |
115 |
116 | class InputRadio(object):
117 | def __init__(self, attr=None, text_value_list=None, checked_value=None):
118 | """
119 | :param attr: 生成的HTML属性,如:{'id': '123'}
120 | :param text_value_list: 生成radio的value和内容,如:
121 | [
122 | {'value':1, 'text': '篮球'},
123 | {'value':2, 'text': '足球'},
124 | {'value':3, 'text': '乒乓球'},
125 | {'value':4, 'text': '羽毛球'},
126 | ]
127 | :param checked_value: 被选中的checked_value,如:2
128 | :return:
129 | """
130 | attr_dict = {'type': 'radio'}
131 | if attr:
132 | attr_dict.update(attr)
133 | self.attr = attr_dict
134 |
135 | self.text_value_list = text_value_list if text_value_list else []
136 | self.checked_value = checked_value
137 |
138 | def __str__(self):
139 | """
140 | 使用对象时返回的字符串
141 | :return:
142 | """
143 | tag_list = []
144 | for item in self.text_value_list:
145 | a = "%s%s
"
146 | b = ""
147 | attr_list = []
148 | for k, v in self.attr.items():
149 | temp = "%s='%s' " % (k, v,)
150 | attr_list.append(temp)
151 | attr_list.append("%s='%s' " % ('value', item['value']))
152 | if item['value'] == self.checked_value:
153 | attr_list.append("checked='checked' ")
154 | input_tag = b % (''.join(attr_list))
155 | c = a % (input_tag,item['text'])
156 | tag_list.append(c)
157 | return ''.join(tag_list)
158 |
159 |
160 | class SingleSelect(object):
161 | def __init__(self, attr=None, text_value_list=None, selected_value=None):
162 | """
163 | :param attr: 生成的HTML属性,如:{'id': '123'}
164 | :param text_value_list: 生成select的value和内容,如:
165 | [
166 | {'value':1, 'text': '篮球'},
167 | {'value':2, 'text': '足球'},
168 | {'value':3, 'text': '乒乓球'},
169 | {'value':4, 'text': '羽毛球'},
170 | ]
171 | :param selected_value: 被选中的checked_value,如:2
172 | :return:
173 | """
174 | attr_dict = {}
175 | if attr:
176 | attr_dict.update(attr)
177 | self.attr = attr_dict
178 |
179 | self.text_value_list = text_value_list if text_value_list else []
180 | self.selected_value = selected_value
181 |
182 | def __str__(self):
183 | """
184 | 使用对象时返回的字符串
185 | :return:
186 | """
187 |
188 | a = ""
189 |
190 | attr_list = []
191 | for k, v in self.attr.items():
192 | temp = "%s='%s' " % (k, v,)
193 | attr_list.append(temp)
194 |
195 | option_list = []
196 |
197 | for item in self.text_value_list:
198 |
199 | if item['value'] == self.selected_value:
200 | b = "%s"
201 | else:
202 | b = "%s"
203 | option = b % (item['value'], item['text'],)
204 | option_list.append(option)
205 |
206 | tag = a % (''.join(attr_list), ''.join(option_list))
207 |
208 | return tag
209 |
210 |
211 | class MultiSelect(object):
212 | def __init__(self, attr=None, text_value_list=None, selected_value_list=None):
213 | """
214 | :param attr: 生成的Select标签的属性,如:{'id': '123'}
215 | :param text_value_list: 生成CheckBox的value和内容,如:
216 | [
217 | {'value':1, 'text': '篮球'},
218 | {'value':2, 'text': '足球'},
219 | {'value':3, 'text': '乒乓球'},
220 | {'value':4, 'text': '羽毛球'},
221 | ]
222 | :param selected_value_list: selected_value_list,如:[2,3,4]
223 | :return:
224 | """
225 | attr_dict = {'multiple': 'multiple'}
226 | if attr:
227 | attr_dict.update(attr)
228 | self.attr = attr_dict
229 |
230 | self.text_value_list = text_value_list if text_value_list else []
231 | self.selected_value_list = selected_value_list if selected_value_list else []
232 |
233 | def __str__(self):
234 | """
235 | 使用对象时返回的字符串
236 | :return:
237 | """
238 |
239 | a = ""
240 |
241 | attr_list = []
242 | for k, v in self.attr.items():
243 | temp = "%s='%s' " % (k, v,)
244 | attr_list.append(temp)
245 |
246 | option_list = []
247 | for item in self.text_value_list:
248 | if item['value'] in self.selected_value_list:
249 | b = "%s"
250 | else:
251 | b = "%s"
252 | option = b % (item['value'], item['text'],)
253 | option_list.append(option)
254 |
255 | tag = a % (''.join(attr_list), ''.join(option_list))
256 | return tag
257 |
258 |
259 | class TextArea(object):
260 | def __init__(self, attr=None, value=""):
261 | """
262 | :param attr: 生成的HTML属性,如:{'id': '123'}
263 | :return:
264 | """
265 | self.attr = attr if attr else {}
266 | self.value = value
267 |
268 | def __str__(self):
269 | """
270 | 使用对象时返回的字符串
271 | :return:
272 | """
273 | t = ""
274 | attr_list = []
275 | for k, v in self.attr.items():
276 | temp = "%s='%s' " % (k, v,)
277 | attr_list.append(temp)
278 | tag = t % (''.join(attr_list), self.value)
279 | return tag
280 |
281 |
--------------------------------------------------------------------------------
/Tyrion/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | from Tyrion.Framework import FrameworkFactory
4 | from Tyrion.Framework import Tornado
5 | from Tyrion.Framework import Django
6 | from Tyrion.Framework import Bottle
7 | from Tyrion.Framework import Flask
8 |
9 |
10 | __version__ = '1.0.1'
11 |
12 | def setup(framework='tornado'):
13 | """
14 | 设置Tyrion插件当前处理的Web框架
15 | :param framework: Web框架的字符串表示
16 | :return:
17 | """
18 | framework_dict = {
19 | 'tornado': Tornado,
20 | 'django': Django,
21 | 'bottle': Bottle,
22 | 'flask': Flask
23 | }
24 | cls = framework_dict.get(framework)
25 | if cls:
26 | FrameworkFactory.set_framework(cls())
27 | else:
28 | raise Exception('Tyrion模块setup方法参数必须为:%s (任意一种字符串)' % ','.join(framework_dict.keys()))
29 |
30 |
31 | """
32 | 使用方法:导入模块并且设置使得其支持不同的Web框架
33 |
34 | 如:
35 | import Tyrion
36 | Tyrion.setup('tornado')
37 |
38 | """
39 |
40 |
--------------------------------------------------------------------------------
/Tyrion/__pycache__/Fields.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WuPeiqi/Tyrion/0fec264c975d40a2fa8412c29d63fd48cd5df49b/Tyrion/__pycache__/Fields.cpython-35.pyc
--------------------------------------------------------------------------------
/Tyrion/__pycache__/Forms.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WuPeiqi/Tyrion/0fec264c975d40a2fa8412c29d63fd48cd5df49b/Tyrion/__pycache__/Forms.cpython-35.pyc
--------------------------------------------------------------------------------
/Tyrion/__pycache__/Framework.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WuPeiqi/Tyrion/0fec264c975d40a2fa8412c29d63fd48cd5df49b/Tyrion/__pycache__/Framework.cpython-35.pyc
--------------------------------------------------------------------------------
/Tyrion/__pycache__/Widget.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WuPeiqi/Tyrion/0fec264c975d40a2fa8412c29d63fd48cd5df49b/Tyrion/__pycache__/Widget.cpython-35.pyc
--------------------------------------------------------------------------------
/Tyrion/__pycache__/__init__.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WuPeiqi/Tyrion/0fec264c975d40a2fa8412c29d63fd48cd5df49b/Tyrion/__pycache__/__init__.cpython-35.pyc
--------------------------------------------------------------------------------
/dist/PyTyrion-1.0.1.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WuPeiqi/Tyrion/0fec264c975d40a2fa8412c29d63fd48cd5df49b/dist/PyTyrion-1.0.1.tar.gz
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 | """A setuptools based setup module.
4 |
5 | See:
6 | https://packaging.python.org/en/latest/distributing.html
7 | https://github.com/pypa/sampleproject
8 | """
9 |
10 | # Always prefer setuptools over distutils
11 | from setuptools import setup, find_packages
12 | # To use a consistent encoding
13 | from codecs import open
14 | from os import path
15 | import re
16 |
17 | here = path.abspath(path.dirname(__file__))
18 |
19 | # Get the long description from the README file
20 | with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
21 | long_description = f.read()
22 |
23 |
24 | def read(*parts):
25 | # intentionally *not* adding an encoding option to open, See:
26 | # https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
27 | return open(path.join(here, *parts), mode='r',encoding='utf-8').read()
28 |
29 |
30 | def find_version(*file_paths):
31 | version_file = read(*file_paths)
32 | version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
33 | version_file, re.M)
34 | if version_match:
35 | return version_match.group(1)
36 | raise RuntimeError("Unable to find version string.")
37 |
38 |
39 | setup(
40 | name='PyTyrion',
41 |
42 | # Versions should comply with PEP440. For a discussion on single-sourcing
43 | # the version across setup.py and the project code, see
44 | # https://packaging.python.org/en/latest/single_source_version.html
45 | version=find_version("Tyrion", "__init__.py"),
46 |
47 | description='支持Tornado、Django、Bottle、Flask的Web表单验证',
48 | long_description=long_description,
49 |
50 | # The project's main homepage.
51 | url='https://github.com/WuPeiqi/Tyrion',
52 |
53 | # Author details
54 | author='wupeiqi',
55 | author_email='wupeiq@live.com',
56 |
57 | # Choose your license
58 | license='MIT',
59 |
60 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
61 | classifiers=[
62 | # How mature is this project? Common values are
63 | # 3 - Alpha
64 | # 4 - Beta
65 | # 5 - Production/Stable
66 | 'Development Status :: 4 - Beta',
67 |
68 | # Indicate who your project is intended for
69 | 'Intended Audience :: Developers',
70 | 'Topic :: Software Development :: Build Tools',
71 |
72 | # Pick your license as you wish (should match "license" above)
73 | 'License :: OSI Approved :: MIT License',
74 |
75 | # Specify the Python versions you support here. In particular, ensure
76 | # that you indicate whether you support Python 2, Python 3 or both.
77 | 'Programming Language :: Python :: 2',
78 | 'Programming Language :: Python :: 2.6',
79 | 'Programming Language :: Python :: 2.7',
80 | 'Programming Language :: Python :: 3',
81 | 'Programming Language :: Python :: 3.3',
82 | 'Programming Language :: Python :: 3.4',
83 | 'Programming Language :: Python :: 3.5',
84 | ],
85 |
86 | keywords='web form python tornado django bottle flask',
87 |
88 | packages=find_packages(),
89 |
90 | )
91 |
--------------------------------------------------------------------------------