Python 框架- Tornado

Tornado 是可扩展的非阻塞式WEB服务器及其相关工具的开源版本。 Tornado 和想在的主流web服务器框架区别:它是非阻塞式服务器,而且速度相当快。得力于非阻塞式方式和对epoll的运用。tornado 每秒可以处理千计的连接。

一:安装

1 pip install tornado
2 源码安装:https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz

 

二: 框架的使用

快速上手

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3    
 4 import tornado.ioloop
 5 import tornado.web
 6    
 7    
 8 class MainHandler(tornado.web.RequestHandler):
 9     def get(self):
10         self.write("Hello, world")
11    
12 application = tornado.web.Application([
13     (r"/index", MainHandler),
14 ])
15    
16    
17 if __name__ == "__main__":
18     application.listen(8888)
19     tornado.ioloop.IOLoop.instance().start()

一:继承requesthandler方法。 创建get方法。

二:配置applicatation  路由映射。

三:执行脚本,监听8888端口。

四: 浏览器访问客户端 http://127.0.0.1:8888/index/ 

五:服务器接受请求,病交给对应的累处理该请求。

六:类接受请求后,根据请求方式(post,get,delete,put。。。等)不同的调用病执行相应的方法

七:将方法返回的字符串内容返回给浏览器。

 

获取用户输入的数据

self.get_argument('xxxx')

    get: 得到URL输入的参数

    post: 得到表单提交等参数。

 

配置静态文件模板路径

static_path 指明了静态文件所在的路径。
static_path_prefix 表示静态文件的路径前缀。 也可以修改为其他的前缀。例如 /mm/ ,然后再浏览网页的时候会发现静态文件的路径显示为/mm/xxxx

settings = {
'template_path': 'template',
'static_path': 'static',
'static_url_prefix': '/static/',
'ui_methods': mt,
'ui_modules': md,
}

application = tornado.web.Application([
(r"/index", MainHandler),
], **settings) //**settings 指settings字典

 

三、路由系统

路由系统指的是URL和类的对应关系转换。在其他的很多框架中url对应函数。在tornado中,url对应一个类。

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('index')

class HomeHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('Home')

settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
}

application = tornado.web.Application([
    (r"/index/", IndexHandler),
     (r"/home/", HomeHandler),
], **settings)

if __name__ == "__main__":
    application.listen(8009)
    tornado.ioloop.IOLoop.instance().start()

在tornado中支持二级路由

如果有下列代码,在add_handlers 中添加了一个二级域名,在进行访问的时候,会优先处理StuHandler

application.add_handlers('stu.aa.com', [
    (r'/index/',StuHandler),

 

 

基于正则的动态路由

1: 使用(\d*)正则表示输入的数据。 浏览器中输入 http://127.0.0.1/124/231。 此时顺序传递参数。

1 application = tornado.web.Application([
2     (r"/index/(\d*)/(\d*)",home.IndexHandler),
3 ],**settings)

2:也可以通过制定参数名称传递参数

1 application = tornado.web.Application([
2     (r"/index/(?P<num>\d*)/(?P<nid>\d*)",home.IndexHandler),
3 ],**settings)

 传递过来的参数在第一种情况下顺序匹配。 第二种情况下按照名称匹配。

1 class IndexHandler(tornado.web.RequestHandler):
2     def get(self,nid,num):
3         print(nid,num)

 

四、模板引擎

Tornado中的模板语言和digango类似。 模板引擎讲模板文件载入到内存,然后将数据嵌入其中。 最终获取到一个完成的字符串。在将字符串返回给请求者。

Tornado的模板支持“控制语句”和“表达语句”。控制语句是使用{% 和 %} 包起来。 例如{%if len(items)>2 %}  表达式语句是使用{{ 和 }} 包起来的。例如{{ item[0] }}。

 

控制语句和对应的python语句的格式基本完全相同。我们支持使用if、for、while、try。这些语句逻辑解释的位置需要使用{% end %} 做标记。 还通过 extends 和block 语句实现了模板继承。 这些在template 模块的代码文档中有详细描述。

在使用模板前需要在setting中设置模板路径: “template_path” : "tpl" 

 

基本使用:

1:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 5     <title>老男孩</title>
 6     <!--<link href='{{static_url("css/common.css")}}' rel="stylesheet" />-->
 7 </head>
 8 <body>
 9 
10     <div>
11         <ul>
12             {% for item in list_info %}
13                 <li>{{item}}</li>
14             {% end %}
15         </ul>
16     </div>
17 
18     <!--<script src='{{static_url("js/jqurey-3.1.0.js")}}'></script>-->
19 
20 </body>
21 </html>
index
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import tornado.ioloop
 5 import tornado.web
 6 
 7 
 8 class MainHandler(tornado.web.RequestHandler):
 9     def get(self):
10         print("ok1")
11         self.render("index.html", list_info=[11, 22, 33])
12 
13 settings = {
14     'template_path': 'tpl',
15     'static_path': 'static',
16     'static_url_prefix': '/static/',
17 }
18 application = tornado.web.Application([
19     (r"/index/", MainHandler),
20 ],**settings)
21 
22 if __name__ == "__main__":
23     application.listen(8888)
24     tornado.ioloop.IOLoop.instance().start()
APP.py

 

2:其他常用方法

在模板中默认提供了一些函数、字段、类以供模板使用:

escape: tornado.escape.xhtml_escape 的別名
xhtml_escape: tornado.escape.xhtml_escape 的別名
url_escape: tornado.esca
 1 {% extends 'layout.html'%}
 2 {% block CSS %}
 3     <link href="{{static_url("css/index.css")}}" rel="stylesheet" />
 4 {% end %}
 5 
 6 {% block RenderBody %}
 7     <h1>Index</h1>
 8 
 9     <ul>
10     {%  for item in li %}
11         <li>{{item}}</li>
12     {% end %}
13     </ul>
14 
15 {% end %}
16 
17 {% block JavaScript %}
18     
19 {% end %}
20 
21 index.html
index.html

 

pe.url_escape 的別名
json_encode: tornado.escape.json_encode 的別名
squeeze: tornado.escape.squeeze 的別名
linkify: tornado.escape.linkify 的別名
datetime: Python 的 datetime 模组
handler: 当前的 RequestHandler 对象
request: handler.request 的別名
current_user: handler.current_user 的別名
locale: handler.locale 的別名
_: handler.locale.translate 的別名
static_url: for handler.static_url 的別名    缓存静态文件 当文件修改的时候,MD5才发生变化
xsrf_form_html: handler.xsrf_form_html 的別名

 

3:母版

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 5     <title>老男孩</title>
 6     <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
 7     {% block CSS %}{% end %}
 8 </head>
 9 <body>
10 
11     <div class="pg-header">
12 
13     </div>
14     
15     {% block RenderBody %}{% end %}
16    
17     <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
18     
19     {% block JavaScript %}{% end %}
20 </body>
21 </html>
22 
23 layout.html
layout.html
 1 {% extends 'layout.html'%}
 2 {% block CSS %}
 3     <link href="{{static_url("css/index.css")}}" rel="stylesheet" />
 4 {% end %}
 5 
 6 {% block RenderBody %}
 7     <h1>Index</h1>
 8 
 9     <ul>
10     {%  for item in li %}
11         <li>{{item}}</li>
12     {% end %}
13     </ul>
14 
15 {% end %}
16 
17 {% block JavaScript %}
18     
19 {% end %}
20 
21 index.html
index.htm

 

4: 导入

1 <div>
2     <ul>
3         <li>1024</li>
4         <li>42区</li>
5     </ul>
6 </div>
7 
8 header.html
header.html
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 5     <title>老男孩</title>
 6     <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
 7 </head>
 8 <body>
 9 
10     <div class="pg-header">
11         {% include 'header.html' %}
12     </div>
13     
14     <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>
15     
16 </body>
17 </html>
18 
19 index.html
index.html

 

5: 自定义函数或者自定义类 UImethod 和UImodule

 

1 def func(self):
2     return 123
定义uimethod
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 from tornado.web import UIModule
4 from tornado import escape
5 
6 class custom(UIModule):
7     def render(self, *args, **kwargs):
8         return '<h1>ok</h1>'
定义 uimodule

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #!/usr/bin/env python
 4 # -*- coding:utf-8 -*-
 5 
 6 import tornado.ioloop
 7 import tornado.web
 8 from tornado.escape import linkify
 9 import uimethod as mt
10 import uimodule as me
11 
12 class MainHandler(tornado.web.RequestHandler):
13     def get(self):
14         self.render('index.html')
15 
16 settings = {
17     'template_path': 'tpl',
18     'static_path': 'static',
19     'static_url_prefix': '/static/',
20     'ui_methods': mt,
21     'ui_modules': me,
22 }
23 
24 application = tornado.web.Application([
25     (r"/index/", MainHandler),
26 ], **settings)
27 
28 
29 if __name__ == "__main__":
30     application.listen(8009)
31     tornado.ioloop.IOLoop.instance().start()
路由注册
 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <link href="{{static_url("commons.css")}}" rel="stylesheet" />
 7 </head>
 8 <body>
 9     <h1>hello</h1>
10     {% module custom(123) %}
11     {{ func() }}
12 </body>
html 模板使用

 

五、静态文件

对于静态文件,可以配置静态文件的目录和前端使用时的前缀,并且Tornado 支持静态文件的缓存

下面的实例中  设置了 'static_path': 'static',  后需要去/static/common.js 找文件,在设置了

'static_url_prefix': '/static/' 后默认静态文件目录前缀为static,可以直接写作common.js 

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3  
 4 import tornado.ioloop
 5 import tornado.web
 6  
 7  
 8 class MainHandler(tornado.web.RequestHandler):
 9     def get(self):
10         self.render('home/index.html')
11  
12 settings = {
13     'template_path': 'template',
14     'static_path': 'static',
15     'static_url_prefix': '/static/',
16 }
17  
18 application = tornado.web.Application([
19     (r"/index", MainHandler),
20 ], **settings)
21  
22  
23 if __name__ == "__main__":
24     application.listen(80)
25     tornado.ioloop.IOLoop.instance().start()
26 
27 app.py
app.py
 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <link href="{{static_url("commons.css")}}" rel="stylesheet" />
 7 </head>
 8 <body>
 9     <h1>hello</h1>
10 </body>
11 </html>
index.html

 

使用了静态文件后,静态文件会生成一个MD5值,只有当静态文件发生变化,MD5才会发生变化。这个时候会更新资源。

 

 

六、Cookie

1:普通使用

  • 1:  def set_cookie(self, name, value, domain=None, expires=None, path="/",
  • expires_days=None, **kwargs):
  • 2: self.set_cookie("auth",'1', expires= time.time()+10)    设置cookie  auth 数值为1, 过期时间为10 秒.。

expires_day =7  表示过期为7天 

    domian  指明是具体哪个域名的cookie

    设置后,用户在访问过程中。将携带次cookie

  • 3: selft.get_cookie("auth")  得到cookie的值。
  • 4: 一般在退出的时候,需要清除cookie
  • 5: 在访问的时候,可以携带多个cookie信息。 例如携带用户名称,进行用户区分
    •       self.set_cookie("username",name)
    •   self.set_cookie("auth",1)

2: cookie 签名(加密)

    Cookie 很容易被恶意的客户端伪造。加入你想在 cookie 中保存当前登陆用户的 id 之类的信息,你需要对 cookie 作签名以防止伪造。Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能。 要使用这些方法,你需要在创建应用时提供一个密钥,名字为 cookie_secret。 你可以把它作为一个关键词参数传入应用的设置中:

 

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        if not self.get_secure_cookie("mycookie"):
            self.set_secure_cookie("mycookie", "myvalue")
            self.write("Your cookie was not set yet!")
        else:
            self.write("Your cookie was set!")
             
application = tornado.web.Application([
    (r"/", MainHandler),
], cookie_secret="61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=")
路由文件设置
  1 def _create_signature_v1(secret, *parts):
  2     hash = hmac.new(utf8(secret), digestmod=hashlib.sha1)
  3     for part in parts:
  4         hash.update(utf8(part))
  5     return utf8(hash.hexdigest())
  6 
  7 # 加密
  8 def _create_signature_v2(secret, s):
  9     hash = hmac.new(utf8(secret), digestmod=hashlib.sha256)
 10     hash.update(utf8(s))
 11     return utf8(hash.hexdigest())
 12 
 13 def create_signed_value(secret, name, value, version=None, clock=None,
 14                         key_version=None):
 15     if version is None:
 16         version = DEFAULT_SIGNED_VALUE_VERSION
 17     if clock is None:
 18         clock = time.time
 19 
 20     timestamp = utf8(str(int(clock())))
 21     value = base64.b64encode(utf8(value))
 22     if version == 1:
 23         signature = _create_signature_v1(secret, name, value, timestamp)
 24         value = b"|".join([value, timestamp, signature])
 25         return value
 26     elif version == 2:
 27         # The v2 format consists of a version number and a series of
 28         # length-prefixed fields "%d:%s", the last of which is a
 29         # signature, all separated by pipes.  All numbers are in
 30         # decimal format with no leading zeros.  The signature is an
 31         # HMAC-SHA256 of the whole string up to that point, including
 32         # the final pipe.
 33         #
 34         # The fields are:
 35         # - format version (i.e. 2; no length prefix)
 36         # - key version (integer, default is 0)
 37         # - timestamp (integer seconds since epoch)
 38         # - name (not encoded; assumed to be ~alphanumeric)
 39         # - value (base64-encoded)
 40         # - signature (hex-encoded; no length prefix)
 41         def format_field(s):
 42             return utf8("%d:" % len(s)) + utf8(s)
 43         to_sign = b"|".join([
 44             b"2",
 45             format_field(str(key_version or 0)),
 46             format_field(timestamp),
 47             format_field(name),
 48             format_field(value),
 49             b''])
 50 
 51         if isinstance(secret, dict):
 52             assert key_version is not None, 'Key version must be set when sign key dict is used'
 53             assert version >= 2, 'Version must be at least 2 for key version support'
 54             secret = secret[key_version]
 55 
 56         signature = _create_signature_v2(secret, to_sign)
 57         return to_sign + signature
 58     else:
 59         raise ValueError("Unsupported version %d" % version)
 60 
 61 # 解密
 62 def _decode_signed_value_v1(secret, name, value, max_age_days, clock):
 63     parts = utf8(value).split(b"|")
 64     if len(parts) != 3:
 65         return None
 66     signature = _create_signature_v1(secret, name, parts[0], parts[1])
 67     if not _time_independent_equals(parts[2], signature):
 68         gen_log.warning("Invalid cookie signature %r", value)
 69         return None
 70     timestamp = int(parts[1])
 71     if timestamp < clock() - max_age_days * 86400:
 72         gen_log.warning("Expired cookie %r", value)
 73         return None
 74     if timestamp > clock() + 31 * 86400:
 75         # _cookie_signature does not hash a delimiter between the
 76         # parts of the cookie, so an attacker could transfer trailing
 77         # digits from the payload to the timestamp without altering the
 78         # signature.  For backwards compatibility, sanity-check timestamp
 79         # here instead of modifying _cookie_signature.
 80         gen_log.warning("Cookie timestamp in future; possible tampering %r",
 81                         value)
 82         return None
 83     if parts[1].startswith(b"0"):
 84         gen_log.warning("Tampered cookie %r", value)
 85         return None
 86     try:
 87         return base64.b64decode(parts[0])
 88     except Exception:
 89         return None
 90 
 91 
 92 def _decode_fields_v2(value):
 93     def _consume_field(s):
 94         length, _, rest = s.partition(b':')
 95         n = int(length)
 96         field_value = rest[:n]
 97         # In python 3, indexing bytes returns small integers; we must
 98         # use a slice to get a byte string as in python 2.
 99         if rest[n:n + 1] != b'|':
100             raise ValueError("malformed v2 signed value field")
101         rest = rest[n + 1:]
102         return field_value, rest
103 
104     rest = value[2:]  # remove version number
105     key_version, rest = _consume_field(rest)
106     timestamp, rest = _consume_field(rest)
107     name_field, rest = _consume_field(rest)
108     value_field, passed_sig = _consume_field(rest)
109     return int(key_version), timestamp, name_field, value_field, passed_sig
110 
111 
112 def _decode_signed_value_v2(secret, name, value, max_age_days, clock):
113     try:
114         key_version, timestamp, name_field, value_field, passed_sig = _decode_fields_v2(value)
115     except ValueError:
116         return None
117     signed_string = value[:-len(passed_sig)]
118 
119     if isinstance(secret, dict):
120         try:
121             secret = secret[key_version]
122         except KeyError:
123             return None
124 
125     expected_sig = _create_signature_v2(secret, signed_string)
126     if not _time_independent_equals(passed_sig, expected_sig):
127         return None
128     if name_field != utf8(name):
129         return None
130     timestamp = int(timestamp)
131     if timestamp < clock() - max_age_days * 86400:
132         # The signature has expired.
133         return None
134     try:
135         return base64.b64decode(value_field)
136     except Exception:
137         return None
138 
139 
140 def get_signature_key_version(value):
141     value = utf8(value)
142     version = _get_version(value)
143     if version < 2:
144         return None
145     try:
146         key_version, _, _, _, _ = _decode_fields_v2(value)
147     except ValueError:
148         return None
149 
150     return key_version
内部实现算法
 1 写cookie过程:
 2 
 3 将值进行base64加密
 4 对除值以外的内容进行签名,哈希算法(无法逆向解析)
 5 拼接 签名 + 加密值
 6 读cookie过程:
 7 
 8 读取 签名 + 加密值
 9 对签名进行验证
10 base64解密,获取值内容
签名Cookie的本质是:

 

注:许多API验证机制和安全cookie的实现机制相同。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3  
 4 import tornado.ioloop
 5 import tornado.web
 6  
 7  
 8 class MainHandler(tornado.web.RequestHandler):
 9  
10     def get(self):
11         login_user = self.get_secure_cookie("login_user", None)
12         if login_user:
13             self.write(login_user)
14         else:
15             self.redirect('/login')
16  
17  
18 class LoginHandler(tornado.web.RequestHandler):
19     def get(self):
20         self.current_user()
21  
22         self.render('login.html', **{'status': ''})
23  
24     def post(self, *args, **kwargs):
25  
26         username = self.get_argument('name')
27         password = self.get_argument('pwd')
28         if username == 'yan' and password == '123':
29             self.set_secure_cookie('login_user', 'yan')
30             self.redirect('/')
31         else:
32             self.render('login.html', **{'status': '用户名或密码错误'})
33  
34 settings = {
35     'template_path': 'template',
36     'static_path': 'static',
37     'static_url_prefix': '/static/',
38     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh'
39 }
40  
41 application = tornado.web.Application([
42     (r"/index", MainHandler),
43     (r"/login", LoginHandler),
44 ], **settings)
45  
46  
47 if __name__ == "__main__":
48     application.listen(8888)
49     tornado.ioloop.IOLoop.instance().start()
50 
51 基于Cookie实现用户验证-Demo
带签名的cookie-用户验证1

    @tornado.web.authenticated 提供的用来进行验证用户是否登录的装饰器

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3  
 4 import tornado.ioloop
 5 import tornado.web
 6  
 7 class BaseHandler(tornado.web.RequestHandler):
 8  
 9     def get_current_user(self):
10         return self.get_secure_cookie("login_user")
11  
12 class MainHandler(BaseHandler):
13  
14     @tornado.web.authenticated
15     def get(self):
16         login_user = self.current_user
17         self.write(login_user)
18  
19  
20  
21 class LoginHandler(tornado.web.RequestHandler):
22     def get(self):
23         self.current_user()
24  
25         self.render('login.html', **{'status': ''})
26  
27     def post(self, *args, **kwargs):
28  
29         username = self.get_argument('name')
30         password = self.get_argument('pwd')
31         if username == 'yan' and password == '123':
32             self.set_secure_cookie('login_user', 'yan')
33             self.redirect('/')
34         else:
35             self.render('login.html', **{'status': '用户名或密码错误'})
36  
37 settings = {
38     'template_path': 'template',
39     'static_path': 'static',
40     'static_url_prefix': '/static/',
41     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
42     'login_url': '/login'
43 }
44  
45 application = tornado.web.Application([
46     (r"/index", MainHandler),
47     (r"/login", LoginHandler),
48 ], **settings)
49  
50  
51 if __name__ == "__main__":
52     application.listen(8888)
53     tornado.ioloop.IOLoop.instance().start()
带签名的cookie-用户验证2

 

3:JavaScript操作Cookie

    由于Cookie保存在浏览器端,所以在浏览器端也可以使用JavaScript来操作Cookie。

1 /*
2 设置cookie,指定秒数过期
3  */
4 function setCookie(name,value,expires){
5     var temp = [];
6     var current_date = new Date();
7     current_date.setSeconds(current_date.getSeconds() + 5);
8     document.cookie = name + "= "+ value +";expires=" + current_date.toUTCString();
9 }
对于参数:
domain   指定域名下的cookie
path     域名下指定url中的cookie
secure    https使用
注:jQuery中也有指定的插件 jQuery Cookie 专门用于操作cookie

 

七、CSRF

 跨站伪造请求(Cross-site request forgery)

在设置csrf后,在请求的时候,后端自动会给前端发送一个证书。 此证书也会保存到cookie中

  {{ xsrf_form_html() }}

在html中,需要携带xsrf_form_html 的信息发送到后台。

 

1 settings = {
2     "xsrf_cookies": True,
3 }
4 application = tornado.web.Application([
5     (r"/", MainHandler),
6     (r"/login", LoginHandler),
7 ], **settings)
setting 配置
1 <form action="/new_message" method="post">
2   {{ xsrf_form_html() }}
3   <input type="text" name="message"/>
4   <input type="submit" value="Post"/>
5 </form>
 1 function getCookie(name) {
 2     var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
 3     return r ? r[1] : undefined;
 4 }
 5 
 6 jQuery.postJSON = function(url, args, callback) {
 7     args._xsrf = getCookie("_xsrf");
 8     $.ajax({url: url, data: $.param(args), dataType: "text", type: "POST",
 9         success: function(response) {
10         callback(eval("(" + response + ")"));
11     }});
12 };
使用ajax携带证书
 1  
 2  function SubmitCsrf(){
 3  
 4   var nid = getCookie("_xsrf");
 5   
 6   $.post({
 7    url:'/csrf',
 8    data:{
 9     "k1":"v1",
10     "_xsrf":nid},
11     success:function(callback){
12         console.log(callback);
13         }
14         }
15   )}
使用ajax 携带证书2

 

 八、上传文件操作

   self.get_argument 的本质是通过self.request 获得数据。  所以可以通过self.request 得到参数。 可以通过meta['filename'] 和 meta['body'] 得到我们想要的内容

1: Form表单上传  表单需要填写enctype="multipart/form-data" 

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 5     <title>上传文件</title>
 6 </head>
 7 <body>
 8     <form id="my_form" name="form" action="/index" method="POST"  enctype="multipart/form-data" >
 9         <input name="fff" id="my_file"  type="file" />
10         <input type="submit" value="提交"  />
11     </form>
12 </body>
13 </html>
HTML
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import tornado.ioloop
 5 import tornado.web
 6 
 7 
 8 class MainHandler(tornado.web.RequestHandler):
 9     def get(self):
10 
11         self.render('index.html')
12 
13     def post(self, *args, **kwargs):
14         file_metas = self.request.files["fff"]
15         # print(file_metas)
16         for meta in file_metas:
17             file_name = meta['filename']
18             with open(file_name,'wb') as up:
19                 up.write(meta['body'])
20 
21 settings = {
22     'template_path': 'template',
23 }
24 
25 application = tornado.web.Application([
26     (r"/index", MainHandler),
27 ], **settings)
28 
29 
30 if __name__ == "__main__":
31     application.listen(8000)
32     tornado.ioloop.IOLoop.instance().start()
Python

2:AJAX上传

  Ajax 上传的本质是建立FormData()对象,然后再FormData()中append 数据。然后讲FormData() 提交给后台。

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <input type="file" id="img" />
 9     <input type="button" onclick="UploadFile();" />
10     <script>
11         function UploadFile(){
12             var fileObj = document.getElementById("img").files[0];
13 
14             var form = new FormData();
15             form.append("k1", "v1");
16             form.append("fff", fileObj);
17 
18             var xhr = new XMLHttpRequest();
19             xhr.open("post", '/index', true);
20             xhr.send(form);
21         }
22     </script>
23 </body>
24 </html>
HTML - XMLHttpRequest
 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <input type="file" id="img" />
 9     <input type="button" onclick="UploadFile();" />
10     <script>
11         function UploadFile(){
12             var fileObj = $("#img")[0].files[0];
13             var form = new FormData();
14             form.append("k1", "v1");
15             form.append("fff", fileObj);
16 
17             $.ajax({
18                 type:'POST',
19                 url: '/index',
20                 data: form,
21                 processData: false,  // tell jQuery not to process the data
22                 contentType: false,  // tell jQuery not to set contentType
23                 success: function(arg){
24                     console.log(arg);
25                 }
26             })
27         }
28     </script>
29 </body>
30 </html>
HTML - jQuery
 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <form id="my_form" name="form" action="/index" method="POST"  enctype="multipart/form-data" >
 9         <div id="main">
10             <input name="fff" id="my_file"  type="file" />
11             <input type="button" name="action" value="Upload" onclick="redirect()"/>
12             <iframe id='my_iframe' name='my_iframe' src=""  class="hide"></iframe>
13         </div>
14     </form>
15 
16     <script>
17         function redirect(){
18             document.getElementById('my_iframe').onload = Testt;
19             document.getElementById('my_form').target = 'my_iframe';
20             document.getElementById('my_form').submit();
21 
22         }
23         
24         function Testt(ths){
25             var t = $("#my_iframe").contents().find("body").text();
26             console.log(t);
27         }
28     </script>
29 </body>
30 </html>
HTML - iframe
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import tornado.ioloop
 5 import tornado.web
 6 
 7 
 8 class MainHandler(tornado.web.RequestHandler):
 9     def get(self):
10 
11         self.render('index.html')
12 
13     def post(self, *args, **kwargs):
14         file_metas = self.request.files["fff"]
15         # print(file_metas)
16         for meta in file_metas:
17             file_name = meta['filename']
18             with open(file_name,'wb') as up:
19                 up.write(meta['body'])
20 
21 settings = {
22     'template_path': 'template',
23 }
24 
25 application = tornado.web.Application([
26     (r"/index", MainHandler),
27 ], **settings)
28 
29 
30 if __name__ == "__main__":
31     application.listen(8000)
32     tornado.ioloop.IOLoop.instance().start()
Python 实现

 

 1 <script type="text/javascript">
 2  
 3     $(document).ready(function () {
 4  
 5         $("#formsubmit").click(function () {
 6  
 7             var iframe = $('<iframe name="postiframe" id="postiframe" style="display: none"></iframe>');
 8  
 9             $("body").append(iframe);
10  
11             var form = $('#theuploadform');
12             form.attr("action", "/upload.aspx");
13             form.attr("method", "post");
14  
15             form.attr("encoding", "multipart/form-data");
16             form.attr("enctype", "multipart/form-data");
17  
18             form.attr("target", "postiframe");
19             form.attr("file", $('#userfile').val());
20             form.submit();
21  
22             $("#postiframe").load(function () {
23                 iframeContents = this.contentWindow.document.body.innerHTML;
24                 $("#textarea").html(iframeContents);
25             });
26  
27             return false;
28  
29         });
30  
31     });
32  
33 </script>
34  
35  
36 <form id="theuploadform">
37     <input id="userfile" name="userfile" size="50" type="file" />
38     <input id="formsubmit" type="submit" value="Send File" />
39 </form>
40  
41 <div id="textarea">
42 </div>
扩展:基于iframe实现Ajax上传示例

 

九、验证码

验证码原理在于后台自动创建一张带有随机内容的图片,然后将内容通过img标签输出到页面。

安装图像处理模块:
pip3 install pillow

 

十、自定义Session

 Session是依赖于Cookie实现的

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时携带Cookie,然后只需要从该Session中查找该客户的状态就可以了。

 

1:面向对象的方法

面向对象中通过索引的方式访问对象,需要内部实现 __getitem__ 、__delitem__、__setitem__方法

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3    
 4 class Foo(object):
 5    
 6     def __getitem__(self, key):
 7         print  '__getitem__',key
 8    
 9     def __setitem__(self, key, value):
10         print '__setitem__',key,value
11    
12     def __delitem__(self, key):
13         print '__delitem__',key
14    
15    
16    
17 obj = Foo()
18 result = obj['k1']
19 #obj['k2'] = '123'
20 #del obj['k1']
Python

 

2:Tornado扩展

 Tornado框架中,默认执行Handler的get/post等方法之前默认会执行 initialize方法,所以可以通过自定义的方式使得所有请求在处理前执行操作。

 1 class BaseHandler(tornado.web.RequestHandler):
 2    
 3     def initialize(self):
 4         self.xxoo = "yan"
 5    
 6    
 7 class MainHandler(BaseHandler):
 8    
 9     def get(self):
10         print(self.xxoo)
11         self.write('index')
12  
13 class IndexHandler(BaseHandler):
14    
15     def get(self):
16         print(self.xxoo)
17         self.write('index')
Python

 

3: session

session其实就是定义在服务器端用于保存用户会话的容器,其必须依赖cookie才能实现。

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3   
 4 import tornado.ioloop
 5 import tornado.web
 6 from hashlib import sha1
 7 import os, time
 8   
 9 session_container = {}
10   
11 create_session_id = lambda: sha1('%s%s' % (os.urandom(16), time.time())).hexdigest()
12   
13   
14 class Session(object):
15   
16     session_id = "__sessionId__"
17   
18     def __init__(self, request):
19         session_value = request.get_cookie(Session.session_id)
20         if not session_value:
21             self._id = create_session_id()
22         else:
23             self._id = session_value
24         request.set_cookie(Session.session_id, self._id)
25   
26     def __getitem__(self, key):
27         return session_container[self._id][key]
28   
29     def __setitem__(self, key, value):
30         if session_container.has_key(self._id):
31             session_container[self._id][key] = value
32         else:
33             session_container[self._id] = {key: value}
34   
35     def __delitem__(self, key):
36         del session_container[self._id][key]
37   
38   
39 class BaseHandler(tornado.web.RequestHandler):
40   
41     def initialize(self):
42         # my_session['k1']访问 __getitem__ 方法
43         self.my_session = Session(self)
44   
45   
46 class MainHandler(BaseHandler):
47   
48     def get(self):
49         print self.my_session['c_user']
50         print self.my_session['c_card']
51         self.write('index')
52   
53 class LoginHandler(BaseHandler):
54   
55     def get(self):
56         self.render('login.html', **{'status': ''})
57   
58     def post(self, *args, **kwargs):
59   
60         username = self.get_argument('name')
61         password = self.get_argument('pwd')
62         if username == 'wupeiqi' and password == '123':
63   
64             self.my_session['c_user'] = 'wupeiqi'
65             self.my_session['c_card'] = '12312312309823012'
66   
67             self.redirect('/index')
68         else:
69             self.render('login.html', **{'status': '用户名或密码错误'})
70   
71 settings = {
72     'template_path': 'template',
73     'static_path': 'static',
74     'static_url_prefix': '/static/',
75     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
76     'login_url': '/login'
77 }
78   
79 application = tornado.web.Application([
80     (r"/index", MainHandler),
81     (r"/login", LoginHandler),
82 ], **settings)
83   
84   
85 if __name__ == "__main__":
86     application.listen(8888)
87     tornado.ioloop.IOLoop.instance().start()
自定义session实现

 

练习:

 1 #!/usr/bin/evn python
 2 #-*- coding:utf-8 -*-
 3 import tornado.ioloop
 4 import tornado.web
 5 
 6 
 7 container = {}
 8 class IndexHandler(tornado.web.RequestHandler):
 9     def get(self):
10         if self.get_argument("u",None) in ["yan","yy"]:
11             import hashlib
12             import time
13             obj = hashlib.md5()
14             obj.update(bytes(str(time.time()),encoding="utf-8"))
15             random_str = obj.hexdigest()
16             container[random_str] = {}
17             container[random_str]["k1"] = 123
18             container[random_str]["k2"] = self.get_argument("u",None) + "parent"
19             container[random_str]["is_login"] = True
20             self.set_cookie("aaaaa",random_str)
21 
22         else:
23             self.write("请登录")
24 
25 
26 
27 
28 class ManageHandler(tornado.web.RequestHandler):
29     def get(self):
30         random_str = self.get_cookie("aaaaa")
31 
32         current_user_info = container.get(random_str,"")
33         if not current_user_info:
34             self.redirect("/index/")
35 
36         else:
37             if current_user_info.get("is_login",None):
38                 temp = "%s -%s"%(current_user_info.get("k1",""),current_user_info.get("k2",""))
39                 self.write(temp)
40 
41             else:
42                 self.redirect("/index/")
43 
44 
45 
46 
47 
48 
49 settings = {
50     'template_path': 'view',
51     'static_path': 'statics',
52     'static_url_prefix': '/static/',
53 }
54 application = tornado.web.Application([
55     (r"/index/", IndexHandler),
56     (r"/manage/", ManageHandler)
57 ],**settings)
58 
59 
60 
61 
62 if __name__ == "__main__":
63     application.listen(8880)
64     tornado.ioloop.IOLoop.instance().start()
练习1
  1 #!/usr/bin/evn python
  2 #-*- coding:utf-8 -*-
  3 import tornado.ioloop
  4 import tornado.web
  5 
  6 
  7 container = {}
  8 
  9 
 10 class Session:
 11     def __init__(self, handler):
 12         self.handler = handler
 13         self.random_str = None
 14 
 15 
 16     def __generate_randomstr(self):
 17         import hashlib
 18         import time
 19         obj = hashlib.md5()
 20         obj.update(bytes(str(time.time()), encoding="utf-8"))
 21         random_str = obj.hexdigest()
 22         return random_str
 23 
 24     def set_value(self,key,value):
 25         #在container中设置随机字符串
 26         #定义专属自己的数据
 27         #在客户端写入随机字符串
 28         if not self.random_str:
 29             random_str = self.handler.get_cookie("__aaa")
 30             if not random_str:
 31                 random_str = self.__generate_randomstr()
 32                 container[random_str] = {}
 33             else:
 34                 #客户端有随机字符串
 35                 if random_str in container.keys():
 36                     pass
 37                 else:
 38                     random_str = self.__generate_randomstr()
 39                     container[random_str] = {}
 40             self.random_str = random_str
 41         container[self.random_str][key] = value
 42 
 43         self.handler.set_cookie("__aaa", self.random_str)
 44 
 45 
 46 
 47     def get_value(self,key):
 48         #获取客户端的随机字符串
 49         #从container中得到专属信息。得到key的值
 50         random_str = self.handler.get_cookie("__aaa")
 51         if not random_str:
 52             return None
 53 
 54         user_info_dict = container.get(random_str,None)
 55 
 56         if not user_info_dict:
 57             return None
 58             #客户端有该随机字符串
 59 
 60         value = user_info_dict.get(key,None)
 61         return value
 62 
 63 
 64 class IndexHandler(tornado.web.RequestHandler):
 65     def get(self):
 66         if self.get_argument("u", None) in ["yan", "yy"]:
 67             s = Session(self)
 68             s.set_value("is_login",True)
 69             s.set_value("name", self.get_argument("u"))
 70         else:
 71             self.write("请登录")
 72 
 73 
 74 class ManageHandler(tornado.web.RequestHandler):
 75     def get(self):
 76         s = Session(self)
 77         value = s.get_value("is_login")
 78         if value:
 79             self.write(s.get_value("name"))
 80         else:
 81             self.write("失败")
 82 
 83 
 84 
 85 
 86 
 87 
 88 settings = {
 89     'template_path': 'view',
 90     'static_path': 'statics',
 91     'static_url_prefix': '/static/',
 92 }
 93 application = tornado.web.Application([
 94     (r"/index/", IndexHandler),
 95     (r"/manage/", ManageHandler)
 96 ],**settings)
 97 
 98 
 99 
100 
101 if __name__ == "__main__":
102     application.listen(8880)
103     tornado.ioloop.IOLoop.instance().start()
练习2
  1 #!/usr/bin/evn python
  2 #-*- coding:utf-8 -*-
  3 import tornado.ioloop
  4 import tornado.web
  5 
  6 
  7 container = {}
  8 
  9 
 10 class Session:
 11     def __init__(self, handler):
 12         self.handler = handler
 13         self.random_str = None
 14 
 15 
 16     def __generate_randomstr(self):
 17         import hashlib
 18         import time
 19         obj = hashlib.md5()
 20         obj.update(bytes(str(time.time()), encoding="utf-8"))
 21         random_str = obj.hexdigest()
 22         return random_str
 23 
 24     def set_value(self,key,value):
 25         #在container中设置随机字符串
 26         #定义专属自己的数据
 27         #在客户端写入随机字符串
 28         if not self.random_str:
 29             random_str = self.handler.get_cookie("__aaa")
 30             if not random_str:
 31                 random_str = self.__generate_randomstr()
 32                 container[random_str] = {}
 33             else:
 34                 #客户端有随机字符串
 35                 if random_str in container.keys():
 36                     pass
 37                 else:
 38                     random_str = self.__generate_randomstr()
 39                     container[random_str] = {}
 40             self.random_str = random_str
 41         container[self.random_str][key] = value
 42 
 43         self.handler.set_cookie("__aaa", self.random_str)
 44 
 45 
 46 
 47     def get_value(self,key):
 48         #获取客户端的随机字符串
 49         #从container中得到专属信息。得到key的值
 50         random_str = self.handler.get_cookie("__aaa")
 51         if not random_str:
 52             return None
 53 
 54         user_info_dict = container.get(random_str,None)
 55 
 56         if not user_info_dict:
 57             return None
 58             #客户端有该随机字符串
 59 
 60         value = user_info_dict.get(key,None)
 61         return value
 62 
 63 
 64 
 65 
 66 class BaseHandler(tornado.web.RequestHandler):
 67     def initialize(self):
 68         self.session = Session(self)
 69 
 70 
 71 class IndexHandler(BaseHandler):
 72     def get(self):
 73         if self.get_argument("u", None) in ["yan", "yy"]:
 74             self.session.set_value("is_login",True)
 75             self.session.set_value("name", self.get_argument("u"))
 76         else:
 77             self.write("请登录")
 78 
 79 
 80 class ManageHandler(BaseHandler):
 81     def get(self):
 82         value = self.session.get_value("is_login")
 83         if value:
 84             self.write(self.session.get_value("name"))
 85         else:
 86             self.write("失败")
 87 
 88 
 89 
 90 
 91 
 92 
 93 settings = {
 94     'template_path': 'view',
 95     'static_path': 'statics',
 96     'static_url_prefix': '/static/',
 97 }
 98 application = tornado.web.Application([
 99     (r"/index/", IndexHandler),
100     (r"/manage/", ManageHandler)
101 ],**settings)
102 
103 
104 
105 
106 if __name__ == "__main__":
107     application.listen(8880)
108     tornado.ioloop.IOLoop.instance().start()
练习3
  1 #!/usr/bin/evn python
  2 #-*- coding:utf-8 -*-
  3 import tornado.ioloop
  4 import tornado.web
  5 
  6 
  7 container = {}
  8 
  9 
 10 class Session:
 11     def __init__(self, handler):
 12         self.handler = handler
 13         self.random_str = None
 14 
 15 
 16     def __generate_randomstr(self):
 17         import hashlib
 18         import time
 19         obj = hashlib.md5()
 20         obj.update(bytes(str(time.time()), encoding="utf-8"))
 21         random_str = obj.hexdigest()
 22         return random_str
 23 
 24     #def set_value(self,key,value):
 25     def __setitem__(self, key, value):
 26         #在container中设置随机字符串
 27         #定义专属自己的数据
 28         #在客户端写入随机字符串
 29         if not self.random_str:
 30             random_str = self.handler.get_cookie("__aaa")
 31             if not random_str:
 32                 random_str = self.__generate_randomstr()
 33                 container[random_str] = {}
 34             else:
 35                 #客户端有随机字符串
 36                 if random_str in container.keys():
 37                     pass
 38                 else:
 39                     random_str = self.__generate_randomstr()
 40                     container[random_str] = {}
 41             self.random_str = random_str
 42         container[self.random_str][key] = value
 43 
 44         self.handler.set_cookie("__aaa", self.random_str)
 45 
 46 
 47 
 48     #def get_value(self,key):
 49     def __getitem__(self, key):
 50         #获取客户端的随机字符串
 51         #从container中得到专属信息。得到key的值
 52         random_str = self.handler.get_cookie("__aaa")
 53         if not random_str:
 54             return None
 55 
 56         user_info_dict = container.get(random_str,None)
 57 
 58         if not user_info_dict:
 59             return None
 60             #客户端有该随机字符串
 61 
 62         value = user_info_dict.get(key,None)
 63         return value
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 class BaseHandler(tornado.web.RequestHandler):
 73     def initialize(self):
 74         self.session = Session(self)
 75 
 76 
 77 class IndexHandler(BaseHandler):
 78     def get(self):
 79         if self.get_argument("u", None) in ["yan", "yy"]:
 80             self.session["is_login"]=True
 81             self.session["name"] = self.get_argument("u")
 82         else:
 83             self.write("请登录")
 84 
 85 
 86 class ManageHandler(BaseHandler):
 87     def get(self):
 88         value = self.session["is_login"]
 89         if value:
 90             self.write(self.session["name"])
 91         else:
 92             self.write("失败")
 93 
 94 
 95 
 96 
 97 
 98 
 99 settings = {
100     'template_path': 'view',
101     'static_path': 'statics',
102     'static_url_prefix': '/static/',
103 }
104 application = tornado.web.Application([
105     (r"/index/", IndexHandler),
106     (r"/manage/", ManageHandler)
107 ],**settings)
108 
109 
110 
111 
112 if __name__ == "__main__":
113     application.listen(8880)
114     tornado.ioloop.IOLoop.instance().start()
练习4

 

4:扩展分布式Session

  1 #!/usr/bin/env python
  2 #coding:utf-8
  3 
  4 import sys
  5 import math
  6 from bisect import bisect
  7 
  8 
  9 if sys.version_info >= (2, 5):
 10     import hashlib
 11     md5_constructor = hashlib.md5
 12 else:
 13     import md5
 14     md5_constructor = md5.new
 15 
 16 
 17 class HashRing(object):
 18     """一致性哈希"""
 19     
 20     def __init__(self,nodes):
 21         '''初始化
 22         nodes : 初始化的节点,其中包含节点已经节点对应的权重
 23                 默认每一个节点有32个虚拟节点
 24                 对于权重,通过多创建虚拟节点来实现
 25                 如:nodes = [
 26                         {'host':'127.0.0.1:8000','weight':1},
 27                         {'host':'127.0.0.1:8001','weight':2},
 28                         {'host':'127.0.0.1:8002','weight':1},
 29                     ]
 30         '''
 31         
 32         self.ring = dict()
 33         self._sorted_keys = []
 34 
 35         self.total_weight = 0
 36         
 37         self.__generate_circle(nodes)
 38         
 39             
 40             
 41     def __generate_circle(self,nodes):
 42         for node_info in nodes:
 43             self.total_weight += node_info.get('weight',1)
 44             
 45         for node_info in nodes:
 46             weight = node_info.get('weight',1)
 47             node = node_info.get('host',None)
 48                 
 49             virtual_node_count = math.floor((32*len(nodes)*weight) / self.total_weight)
 50             for i in xrange(0,int(virtual_node_count)):
 51                 key = self.gen_key_thirty_two( '%s-%s' % (node, i) )
 52                 if self._sorted_keys.__contains__(key):
 53                     raise Exception('该节点已经存在.')
 54                 self.ring[key] = node
 55                 self._sorted_keys.append(key)
 56             
 57     def add_node(self,node):
 58         ''' 新建节点
 59         node : 要添加的节点,格式为:{'host':'127.0.0.1:8002','weight':1},其中第一个元素表示节点,第二个元素表示该节点的权重。
 60         '''
 61         node = node.get('host',None)
 62         if not node:
 63                 raise Exception('节点的地址不能为空.')
 64                 
 65         weight = node.get('weight',1)
 66         
 67         self.total_weight += weight
 68         nodes_count = len(self._sorted_keys) + 1
 69         
 70         virtual_node_count = math.floor((32 * nodes_count * weight) / self.total_weight)
 71         for i in xrange(0,int(virtual_node_count)):
 72             key = self.gen_key_thirty_two( '%s-%s' % (node, i) )
 73             if self._sorted_keys.__contains__(key):
 74                 raise Exception('该节点已经存在.')
 75             self.ring[key] = node
 76             self._sorted_keys.append(key)
 77         
 78     def remove_node(self,node):
 79         ''' 移除节点
 80         node : 要移除的节点 '127.0.0.1:8000'
 81         '''
 82         for key,value in self.ring.items():
 83             if value == node:
 84                 del self.ring[key]
 85                 self._sorted_keys.remove(key)
 86     
 87     def get_node(self,string_key):
 88         '''获取 string_key 所在的节点'''
 89         pos = self.get_node_pos(string_key)
 90         if pos is None:
 91             return None
 92         return self.ring[ self._sorted_keys[pos]].split(':')
 93     
 94     def get_node_pos(self,string_key):
 95         '''获取 string_key 所在的节点的索引'''
 96         if not self.ring:
 97             return None
 98             
 99         key = self.gen_key_thirty_two(string_key)
100         nodes = self._sorted_keys
101         pos = bisect(nodes, key)
102         return pos
103     
104     def gen_key_thirty_two(self, key):
105         
106         m = md5_constructor()
107         m.update(key)
108         return long(m.hexdigest(), 16)
109         
110     def gen_key_sixteen(self,key):
111         
112         b_key = self.__hash_digest(key)
113         return self.__hash_val(b_key, lambda x: x)
114 
115     def __hash_val(self, b_key, entry_fn):
116         return (( b_key[entry_fn(3)] << 24)|(b_key[entry_fn(2)] << 16)|(b_key[entry_fn(1)] << 8)| b_key[entry_fn(0)] )
117 
118     def __hash_digest(self, key):
119         m = md5_constructor()
120         m.update(key)
121         return map(ord, m.digest())
122 
123 
124 """
125 nodes = [
126     {'host':'127.0.0.1:8000','weight':1},
127     {'host':'127.0.0.1:8001','weight':2},
128     {'host':'127.0.0.1:8002','weight':1},
129 ]
130 
131 ring = HashRing(nodes)
132 result = ring.get_node('98708798709870987098709879087')
133 print result
134 
135 """
一致性哈西
 1 from hashlib import sha1
 2 import os, time
 3 
 4 
 5 create_session_id = lambda: sha1('%s%s' % (os.urandom(16), time.time())).hexdigest()
 6 
 7 
 8 class Session(object):
 9 
10     session_id = "__sessionId__"
11 
12     def __init__(self, request):
13         session_value = request.get_cookie(Session.session_id)
14         if not session_value:
15             self._id = create_session_id()
16         else:
17             self._id = session_value
18         request.set_cookie(Session.session_id, self._id)
19 
20     def __getitem__(self, key):
21         # 根据 self._id ,在一致性哈西中找到其对应的服务器IP
22         # 找到相对应的redis服务器,如: r = redis.StrictRedis(host='localhost', port=6379, db=0)
23         # 使用python redis api 链接
24         # 获取数据,即:
25         # return self._redis.hget(self._id, name)
26 
27     def __setitem__(self, key, value):
28         # 根据 self._id ,在一致性哈西中找到其对应的服务器IP
29         # 使用python redis api 链接
30         # 设置session
31         # self._redis.hset(self._id, name, value)
32 
33 
34     def __delitem__(self, key):
35         # 根据 self._id 找到相对应的redis服务器
36         # 使用python redis api 链接
37         # 删除,即:
38         return self._redis.hdel(self._id, name)
session

 

十一、自定义Form表单验证

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <link href="{{static_url("commons.css")}}" rel="stylesheet" />
 7 </head>
 8 <body>
 9     <h1>hello</h1>
10     <form action="/index" method="post">
11 
12         <p>hostname: <input type="text" name="host" /> </p>
13         <p>ip: <input type="text" name="ip" /> </p>
14         <p>port: <input type="text" name="port" /> </p>
15         <p>phone: <input type="text" name="phone" /> </p>
16         <input type="submit" />
17     </form>
18 </body>
19 </html>
HTML
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3   
 4 import tornado.ioloop
 5 import tornado.web
 6 from hashlib import sha1
 7 import os, time
 8 import re
 9   
10   
11 class MainForm(object):
12     def __init__(self):
13         self.host = "(.*)"
14         self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
15         self.port = '(\d+)'
16         self.phone = '^1[3|4|5|8][0-9]\d{8}$'
17   
18     def check_valid(self, request):
19         form_dict = self.__dict__
20         for key, regular in form_dict.items():
21             post_value = request.get_argument(key)
22             # 让提交的数据 和 定义的正则表达式进行匹配
23             ret = re.match(regular, post_value)
24             print key,ret,post_value
25   
26   
27 class MainHandler(tornado.web.RequestHandler):
28     def get(self):
29         self.render('index.html')
30     def post(self, *args, **kwargs):
31         obj = MainForm()
32         result = obj.check_valid(self)
33         self.write('ok')
34   
35   
36   
37 settings = {
38     'template_path': 'template',
39     'static_path': 'static',
40     'static_url_prefix': '/static/',
41     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
42     'login_url': '/login'
43 }
44   
45 application = tornado.web.Application([
46     (r"/index", MainHandler),
47 ], **settings)
48   
49   
50 if __name__ == "__main__":
51     application.listen(8888)
52     tornado.ioloop.IOLoop.instance().start()
简单pyton验证
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 
  4 import tornado.ioloop
  5 import tornado.web
  6 import re
  7 
  8 
  9 class Field(object):
 10 
 11     def __init__(self, error_msg_dict, required):
 12         self.id_valid = False
 13         self.value = None
 14         self.error = None
 15         self.name = None
 16         self.error_msg = error_msg_dict
 17         self.required = required
 18 
 19     def match(self, name, value):
 20         self.name = name
 21 
 22         if not self.required:
 23             self.id_valid = True
 24             self.value = value
 25         else:
 26             if not value:
 27                 if self.error_msg.get('required', None):
 28                     self.error = self.error_msg['required']
 29                 else:
 30                     self.error = "%s is required" % name
 31             else:
 32                 ret = re.match(self.REGULAR, value)
 33                 if ret:
 34                     self.id_valid = True
 35                     self.value = ret.group()
 36                 else:
 37                     if self.error_msg.get('valid', None):
 38                         self.error = self.error_msg['valid']
 39                     else:
 40                         self.error = "%s is invalid" % name
 41 
 42 
 43 class IPField(Field):
 44     REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
 45 
 46     def __init__(self, error_msg_dict=None, required=True):
 47 
 48         error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 49         if error_msg_dict:
 50             error_msg.update(error_msg_dict)
 51 
 52         super(IPField, self).__init__(error_msg_dict=error_msg, required=required)
 53 
 54 
 55 class IntegerField(Field):
 56     REGULAR = "^\d+$"
 57 
 58     def __init__(self, error_msg_dict=None, required=True):
 59         error_msg = {'required': '数字不能为空', 'valid': '数字格式错误'}
 60         if error_msg_dict:
 61             error_msg.update(error_msg_dict)
 62 
 63         super(IntegerField, self).__init__(error_msg_dict=error_msg, required=required)
 64 
 65 
 66 class CheckBoxField(Field):
 67 
 68     def __init__(self, error_msg_dict=None, required=True):
 69         error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 70         if error_msg_dict:
 71             error_msg.update(error_msg_dict)
 72 
 73         super(CheckBoxField, self).__init__(error_msg_dict=error_msg, required=required)
 74 
 75     def match(self, name, value):
 76         self.name = name
 77 
 78         if not self.required:
 79             self.id_valid = True
 80             self.value = value
 81         else:
 82             if not value:
 83                 if self.error_msg.get('required', None):
 84                     self.error = self.error_msg['required']
 85                 else:
 86                     self.error = "%s is required" % name
 87             else:
 88                 if isinstance(name, list):
 89                     self.id_valid = True
 90                     self.value = value
 91                 else:
 92                     if self.error_msg.get('valid', None):
 93                         self.error = self.error_msg['valid']
 94                     else:
 95                         self.error = "%s is invalid" % name
 96 
 97 
 98 class FileField(Field):
 99     REGULAR = "^(\w+\.pdf)|(\w+\.mp3)|(\w+\.py)$"
100 
101     def __init__(self, error_msg_dict=None, required=True):
102         error_msg = {}  # {'required': '数字不能为空', 'valid': '数字格式错误'}
103         if error_msg_dict:
104             error_msg.update(error_msg_dict)
105 
106         super(FileField, self).__init__(error_msg_dict=error_msg, required=required)
107 
108     def match(self, name, value):
109         self.name = name
110         self.value = []
111         if not self.required:
112             self.id_valid = True
113             self.value = value
114         else:
115             if not value:
116                 if self.error_msg.get('required', None):
117                     self.error = self.error_msg['required']
118                 else:
119                     self.error = "%s is required" % name
120             else:
121                 m = re.compile(self.REGULAR)
122                 if isinstance(value, list):
123                     for file_name in value:
124                         r = m.match(file_name)
125                         if r:
126                             self.value.append(r.group())
127                             self.id_valid = True
128                         else:
129                             self.id_valid = False
130                             if self.error_msg.get('valid', None):
131                                 self.error = self.error_msg['valid']
132                             else:
133                                 self.error = "%s is invalid" % name
134                             break
135                 else:
136                     if self.error_msg.get('valid', None):
137                         self.error = self.error_msg['valid']
138                     else:
139                         self.error = "%s is invalid" % name
140 
141     def save(self, request, upload_path=""):
142 
143         file_metas = request.files[self.name]
144         for meta in file_metas:
145             file_name = meta['filename']
146             with open(file_name,'wb') as up:
147                 up.write(meta['body'])
148 
149 
150 class Form(object):
151 
152     def __init__(self):
153         self.value_dict = {}
154         self.error_dict = {}
155         self.valid_status = True
156 
157     def validate(self, request, depth=10, pre_key=""):
158 
159         self.initialize()
160         self.__valid(self, request, depth, pre_key)
161 
162     def initialize(self):
163         pass
164 
165     def __valid(self, form_obj, request, depth, pre_key):
166         """
167         验证用户表单请求的数据
168         :param form_obj: Form对象(Form派生类的对象)
169         :param request: Http请求上下文(用于从请求中获取用户提交的值)
170         :param depth: 对Form内容的深度的支持
171         :param pre_key: Html中name属性值的前缀(多层Form时,内部递归时设置,无需理会)
172         :return: 是否验证通过,True:验证成功;False:验证失败
173         """
174 
175         depth -= 1
176         if depth < 0:
177             return None
178         form_field_dict = form_obj.__dict__
179         for key, field_obj in form_field_dict.items():
180             print key,field_obj
181             if isinstance(field_obj, Form) or isinstance(field_obj, Field):
182                 if isinstance(field_obj, Form):
183                     # 获取以key开头的所有的值,以参数的形式传至
184                     self.__valid(field_obj, request, depth, key)
185                     continue
186                 if pre_key:
187                     key = "%s.%s" % (pre_key, key)
188 
189                 if isinstance(field_obj, CheckBoxField):
190                     post_value = request.get_arguments(key, None)
191                 elif isinstance(field_obj, FileField):
192                     post_value = []
193                     file_list = request.request.files.get(key, None)
194                     for file_item in file_list:
195                         post_value.append(file_item['filename'])
196                 else:
197                     post_value = request.get_argument(key, None)
198 
199                 print post_value
200                 # 让提交的数据 和 定义的正则表达式进行匹配
201                 field_obj.match(key, post_value)
202                 if field_obj.id_valid:
203                     self.value_dict[key] = field_obj.value
204                 else:
205                     self.error_dict[key] = field_obj.error
206                     self.valid_status = False
207 
208 
209 class ListForm(object):
210     def __init__(self, form_type):
211         self.form_type = form_type
212         self.valid_status = True
213         self.value_dict = {}
214         self.error_dict = {}
215 
216     def validate(self, request):
217         name_list = request.request.arguments.keys() + request.request.files.keys()
218         index = 0
219         flag = False
220         while True:
221             pre_key = "[%d]" % index
222             for name in name_list:
223                 if name.startswith(pre_key):
224                     flag = True
225                     break
226             if flag:
227                 form_obj = self.form_type()
228                 form_obj.validate(request, depth=10, pre_key="[%d]" % index)
229                 if form_obj.valid_status:
230                     self.value_dict[index] = form_obj.value_dict
231                 else:
232                     self.error_dict[index] = form_obj.error_dict
233                     self.valid_status = False
234             else:
235                 break
236 
237             index += 1
238             flag = False
239 
240 
241 class MainForm(Form):
242 
243     def __init__(self):
244         # self.ip = IPField(required=True)
245         # self.port = IntegerField(required=True)
246         # self.new_ip = IPField(required=True)
247         # self.second = SecondForm()
248         self.fff = FileField(required=True)
249         super(MainForm, self).__init__()
250 
251 #
252 # class SecondForm(Form):
253 #
254 #     def __init__(self):
255 #         self.ip = IPField(required=True)
256 #         self.new_ip = IPField(required=True)
257 #
258 #         super(SecondForm, self).__init__()
259 
260 
261 class MainHandler(tornado.web.RequestHandler):
262     def get(self):
263         self.render('index.html')
264     def post(self, *args, **kwargs):
265         # for i in  dir(self.request):
266         #     print i
267         # print self.request.arguments
268         # print self.request.files
269         # print self.request.query
270         # name_list = self.request.arguments.keys() + self.request.files.keys()
271         # print name_list
272 
273         # list_form = ListForm(MainForm)
274         # list_form.validate(self)
275         #
276         # print list_form.valid_status
277         # print list_form.value_dict
278         # print list_form.error_dict
279 
280         # obj = MainForm()
281         # obj.validate(self)
282         #
283         # print "验证结果:", obj.valid_status
284         # print "符合验证结果:", obj.value_dict
285         # print "错误信息:"
286         # for key, item in obj.error_dict.items():
287         #     print key,item
288         # print self.get_arguments('favor'),type(self.get_arguments('favor'))
289         # print self.get_argument('favor'),type(self.get_argument('favor'))
290         # print type(self.get_argument('fff')),self.get_argument('fff')
291         # print self.request.files
292         # obj = MainForm()
293         # obj.validate(self)
294         # print obj.valid_status
295         # print obj.value_dict
296         # print obj.error_dict
297         # print self.request,type(self.request)
298         # obj.fff.save(self.request)
299         # from tornado.httputil import HTTPServerRequest
300         # name_list = self.request.arguments.keys() + self.request.files.keys()
301         # print name_list
302         # print self.request.files,type(self.request.files)
303         # print len(self.request.files.get('fff'))
304         
305         # obj = MainForm()
306         # obj.validate(self)
307         # print obj.valid_status
308         # print obj.value_dict
309         # print obj.error_dict
310         # obj.fff.save(self.request)
311         self.write('ok')
312 
313 
314 
315 settings = {
316     'template_path': 'template',
317     'static_path': 'static',
318     'static_url_prefix': '/static/',
319     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
320     'login_url': '/login'
321 }
322 
323 application = tornado.web.Application([
324     (r"/index", MainHandler),
325 ], **settings)
326 
327 
328 if __name__ == "__main__":
329     application.listen(8888)
330     tornado.ioloop.IOLoop.instance().start()
基于正则可重用性的Pyton表单验证

 

练习:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import tornado.ioloop
 5 import tornado.web
 6 from hashlib import sha1
 7 import os, time
 8 import re
 9 
10 
11 
12 class IndexHandler(tornado.web.RequestHandler):
13     def get(self):
14         self.render("index.html")
15 
16     def post(self):
17         obj = IndexForm()
18         is_valid,value_dict = obj.check_valid(self)
19         print(is_valid)
20 
21         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
22 
23         self.write(dict)
24 
25 class HomeHandler(tornado.web.RequestHandler):
26     def get(self):
27         self.render("home.html")
28 
29     def post(self):
30         obj = IndexForm()
31         is_valid,value_dict = obj.check_valid(self)
32         print(is_valid)
33 
34         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
35 
36         self.write(dict)
37 
38 
39 class BaseForm(object):
40     def check_valid(self, handle):
41         flag = True
42         value_dict = {}
43         # 获取当前类的属性字典
44         form_dict = self.__dict__
45 
46         for key, regular in form_dict.items():
47             # 获取用户输入的数据
48             input_value = handle.get_argument(key)
49 
50             # 让提交的数据 和 定义的正则表达式进行匹配  match表示从头到尾匹配
51             ret = re.match(regular, input_value)
52             # 匹配成功ret为返回的一个对象,匹配不成功返回none
53             print(key, ret, input_value)
54 
55             if not ret:
56                 flag = False
57                 value_dict[key] = input_value
58         return flag, value_dict
59 
60 class IndexForm(BaseForm):
61     def __init__(self):
62         self.host = "(.*)"
63         self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
64         self.port = '(\d+)'
65         self.phone = '^1[3|4|5|8][0-9]\d{8}$'
66 
67 class HomeForm(object):
68     def __init__(self):
69         self.host = "(.*)"
70         self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
71 
72 
73 settings = {
74     'template_path': 'views',
75     'static_path': 'statics',
76     'static_url_prefix': '/static/',
77     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
78     'login_url': '/login'
79 }
80 
81 application = tornado.web.Application([
82     (r"/index", IndexHandler),
83     (r"/home", HomeHandler),
84 ], **settings)
85 
86 if __name__ == "__main__":
87     application.listen(8880)
88     tornado.ioloop.IOLoop.instance().start()
IP验证
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 
  4 import tornado.ioloop
  5 import tornado.web
  6 from hashlib import sha1
  7 import os, time
  8 import re
  9 
 10 
 11 class IPField:
 12     #静态字段
 13     REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
 14     def __init__(self, error_msg_dict=None, required=True):
 15         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 16         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
 17         if error_msg_dict:
 18             self.error_msg.update(error_msg_dict)
 19         self.required = required
 20         self.error = None #错误信息
 21         self.is_valid = False #判定格式是否满足
 22         self.value = None #如果匹配成功值是多少
 23 
 24 
 25     def validate(self, name, input_value):
 26         """
 27         :param name:  字段名称
 28         :param input_value:  表单输入内容
 29         :return:
 30         """
 31         if not self.required:
 32             self.is_valid = True
 33             self.value = input_value
 34         else:
 35             if not input_value.strip():   #用户输入为空
 36                 if self.error_msg.get('required', None):  #得到错误信息
 37                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
 38                 else:
 39                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
 40             else:
 41                 ret = re.match(self.REGULAR, input_value)
 42                 if ret:  #如果匹配
 43                     self.id_valid = True
 44                     self.value = input_value
 45                 else:
 46                     if self.error_msg.get('valid', None):
 47                         self.error = self.error_msg['valid']
 48                     else:
 49                         self.error = "%s is invalid" % name
 50 
 51 
 52 class IndexHandler(tornado.web.RequestHandler):
 53     def get(self):
 54         self.render("index.html")
 55 
 56     def post(self):
 57         obj = IndexForm()
 58         is_valid,value_dict = obj.check_valid(self)
 59         print(is_valid)
 60 
 61         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
 62 
 63         self.write(dict)
 64 
 65 class HomeHandler(tornado.web.RequestHandler):
 66     def get(self):
 67         error_value_dict = {}
 68         self.render("home.html",error_dict = error_value_dict)
 69 
 70     def post(self):
 71         obj = HomeForm()
 72         is_valid,success_value_dict,error_value_dict = obj.check_valid(self)
 73         print(is_valid)
 74         if is_valid:
 75             for k,v in success_value_dict.items():
 76                 print(k,v)
 77         else:
 78             for k,v in error_value_dict.items():
 79                 print(k,v)
 80 
 81             self.render("home.html",error_dict = error_value_dict)
 82 
 83         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
 84 
 85 
 86 
 87 class BaseForm(object):
 88     def check_valid(self, handle):
 89         flag = True
 90         value_dict = {}
 91         error_message_dict ={}
 92         success_value_dict = {}
 93         # 获取当前类的属性字典
 94         form_dict = self.__dict__
 95         for key, regular in form_dict.items():
 96             #key  ip
 97             #handle HomeIndex...
 98             #reguler:IPField(required =true)
 99             #在homeform继承baseform的时候,传递的regular是一个IPFiled的对象
100 
101             input_value = handle.get_argument(key)
102 
103             #IPFiled中进行验证
104             regular.validate(key,input_value)
105             if regular.is_valid:
106                 success_value_dict[key]=regular.value
107                 pass
108             else:
109                 error_message_dict[key] = regular.error
110                 flag = False
111 
112         return flag, success_value_dict,error_message_dict
113 
114 class IndexForm(BaseForm):
115     def __init__(self):
116         self.host = "(.*)"
117         self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
118         self.port = '(\d+)'
119         self.phone = '^1[3|4|5|8][0-9]\d{8}$'
120 
121 class HomeForm(BaseForm):
122     def __init__(self):
123         self.ip = IPField(required=True,error_msg_dict = {"required":"不可为空","valid":"格式错误"})
124 
125 
126 
127 settings = {
128     'template_path': 'views',
129     'static_path': 'statics',
130     'static_url_prefix': '/static/',
131     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
132     'login_url': '/login'
133 }
134 
135 application = tornado.web.Application([
136     (r"/index", IndexHandler),
137     (r"/home", HomeHandler),
138 ], **settings)
139 
140 if __name__ == "__main__":
141     application.listen(8880)
142     tornado.ioloop.IOLoop.instance().start()
IP-类实现
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 
  4 import tornado.ioloop
  5 import tornado.web
  6 from hashlib import sha1
  7 import os, time
  8 import re
  9 
 10 
 11 class IPField:
 12     #静态字段
 13     REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
 14     def __init__(self, error_msg_dict=None, required=True):
 15         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 16         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
 17         if error_msg_dict:
 18             self.error_msg.update(error_msg_dict)
 19         self.required = required
 20         self.error = None #错误信息
 21         self.is_valid = False #判定格式是否满足
 22         self.value = None #如果匹配成功值是多少
 23 
 24 
 25     def validate(self, name, input_value):
 26         """
 27         :param name:  字段名称
 28         :param input_value:  表单输入内容
 29         :return:
 30         """
 31 
 32         print('ffffff',name,input_value)
 33         if not self.required:
 34             self.is_valid = True
 35             self.value = input_value
 36         else:
 37             if not input_value.strip():   #用户输入为空
 38                 if self.error_msg.get('required', None):  #得到错误信息
 39                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
 40                 else:
 41                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
 42             else:
 43                 ret = re.match(self.REGULAR, input_value)
 44                 if ret:  #如果匹配
 45                     self.is_valid = True
 46                     self.value = input_value
 47                     print("匹配",self.value)
 48 
 49 
 50                 else:
 51 
 52                     print("不匹配")
 53                     if self.error_msg.get('valid', None):
 54                         self.error = self.error_msg['valid']
 55                     else:
 56                         self.error = "%s is invalid" % name
 57 
 58 
 59 class StringField:
 60     #静态字段
 61     REGULAR = "^(.*)$"
 62     def __init__(self, error_msg_dict=None, required=True):
 63         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 64         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
 65         if error_msg_dict:
 66             self.error_msg.update(error_msg_dict)
 67         self.required = required
 68         self.error = None #错误信息
 69         self.is_valid = False #判定格式是否满足
 70         self.value = None #如果匹配成功值是多少
 71 
 72 
 73     def validate(self, name, input_value):
 74         """
 75         :param name:  字段名称
 76         :param input_value:  表单输入内容
 77         :return:
 78         """
 79         if not self.required:
 80             self.is_valid = True
 81             self.value = input_value
 82         else:
 83             if not input_value.strip():   #用户输入为空
 84                 if self.error_msg.get('required', None):  #得到错误信息
 85                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
 86                 else:
 87                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
 88             else:
 89                 ret = re.match(self.REGULAR, input_value)
 90                 if ret:  #如果匹配
 91                     self.is_valid = True
 92                     self.value = input_value
 93                 else:
 94                     if self.error_msg.get('valid', None):
 95                         self.error = self.error_msg['valid']
 96                     else:
 97                         self.error = "%s is invalid" % name
 98 
 99 
100 class CheckboxField:
101     #checkbox 验证没有值即可
102     def __init__(self, error_msg_dict=None, required=True):
103         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
104         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
105         if error_msg_dict:
106             self.error_msg.update(error_msg_dict)
107         self.required = required
108         self.error = None #错误信息
109         self.is_valid = False #判定格式是否满足
110         self.value = None #如果匹配成功值是多少
111 
112 
113     def validate(self, name, input_value):
114         """
115         :param name:  字段名称favor
116         :param input_value:  表单输入内容
117         :return:
118         """
119         print(name,input_value)
120         if not self.required:
121             self.is_valid = True
122             self.value = input_value
123         else:
124             if not input_value:   #用户输入为空
125                 if self.error_msg.get('required', None):  #得到错误信息
126                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
127                 else:
128                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
129             else:
130                 self.is_valid = True
131                 self.value = input_value
132                 print(name,self.value)
133 
134 class IndexHandler(tornado.web.RequestHandler):
135     def get(self):
136         self.render("index.html")
137 
138     def post(self):
139         obj = IndexForm()
140         is_valid,value_dict = obj.check_valid(self)
141         print(is_valid)
142 
143         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
144 
145         self.write(dict)
146 
147 class HomeHandler(tornado.web.RequestHandler):
148     def get(self):
149         error_value_dict = {}
150         self.render("home.html",error_dict = error_value_dict)
151 
152     def post(self):
153         obj = HomeForm()
154         is_valid,success_value_dict,error_value_dict = obj.check_valid(self)
155         print('aabb',is_valid)
156         if is_valid:
157             for k,v in success_value_dict.items():
158                 print(k,v)
159         else:
160             for k,v in error_value_dict.items():
161                 print(k,v)
162 
163             self.render("home.html",error_dict = error_value_dict)
164 
165         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
166 
167 
168 
169 class BaseForm(object):
170     def check_valid(self, handle):
171         flag = True
172         value_dict = {}
173         error_message_dict ={}
174         success_value_dict = {}
175         # 获取当前类的属性字典
176         form_dict = self.__dict__
177         for key, regular in form_dict.items():
178             #key  ip
179             #handle HomeIndex...
180             #reguler:IPField(required =true)
181             #在homeform继承baseform的时候,传递的regular是一个IPFiled的对象
182             if type(regular) == CheckboxField:
183                 #传递过来的regular 是一个对象
184                 input_value = handle.get_arguments(key)
185 
186                 print(input_value, 'aaaaaa');
187             else:
188                 input_value = handle.get_argument(key)
189 
190             #IPFiled中进行验证
191             regular.validate(key,input_value)
192 
193             if regular.is_valid:
194                 success_value_dict[key]=regular.value
195 
196                 print('regular.value',regular.value)
197 
198             else:
199                 error_message_dict[key] = regular.error
200                 flag = False
201 
202 
203         for a,d in success_value_dict.items():
204             print(a,d)
205 
206         for a, d in error_message_dict.items():
207             print(a, d)
208 
209         return flag, success_value_dict,error_message_dict
210 
211 class IndexForm(BaseForm):
212     def __init__(self):
213         self.host = "(.*)"
214         self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
215         self.port = '(\d+)'
216         self.phone = '^1[3|4|5|8][0-9]\d{8}$'
217 
218 class HomeForm(BaseForm):
219     def __init__(self):
220         self.ip = IPField(required=True,error_msg_dict = {"required":"不可为空","valid":"格式错误"})
221         # self.host = StringField(required=True)
222         self.favor = CheckboxField(required=True)
223 
224 
225 settings = {
226     'template_path': 'views',
227     'static_path': 'statics',
228     'static_url_prefix': '/static/',
229     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
230     'login_url': '/login'
231 }
232 
233 application = tornado.web.Application([
234     (r"/index", IndexHandler),
235     (r"/home", HomeHandler),
236 ], **settings)
237 
238 if __name__ == "__main__":
239     application.listen(8880)
240     tornado.ioloop.IOLoop.instance().start()
Checkbox
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 
  4 import tornado.ioloop
  5 import tornado.web
  6 from hashlib import sha1
  7 import os, time
  8 import re
  9 
 10 
 11 class IPField:
 12     #静态字段
 13     REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
 14     def __init__(self, error_msg_dict=None, required=True):
 15         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 16         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
 17         if error_msg_dict:
 18             self.error_msg.update(error_msg_dict)
 19         self.required = required
 20         self.error = None #错误信息
 21         self.is_valid = False #判定格式是否满足
 22         self.value = None #如果匹配成功值是多少
 23 
 24 
 25     def validate(self, name, input_value):
 26         """
 27         :param name:  字段名称
 28         :param input_value:  表单输入内容
 29         :return:
 30         """
 31 
 32         print('ffffff',name,input_value)
 33         if not self.required:
 34             self.is_valid = True
 35             self.value = input_value
 36         else:
 37             if not input_value.strip():   #用户输入为空
 38                 if self.error_msg.get('required', None):  #得到错误信息
 39                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
 40                 else:
 41                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
 42             else:
 43                 ret = re.match(self.REGULAR, input_value)
 44                 if ret:  #如果匹配
 45                     self.is_valid = True
 46                     self.value = input_value
 47                     print("匹配",self.value)
 48 
 49 
 50                 else:
 51 
 52                     print("不匹配")
 53                     if self.error_msg.get('valid', None):
 54                         self.error = self.error_msg['valid']
 55                     else:
 56                         self.error = "%s is invalid" % name
 57 
 58 
 59 class StringField:
 60     #静态字段
 61     REGULAR = "^(.*)$"
 62     def __init__(self, error_msg_dict=None, required=True):
 63         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 64         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
 65         if error_msg_dict:
 66             self.error_msg.update(error_msg_dict)
 67         self.required = required
 68         self.error = None #错误信息
 69         self.is_valid = False #判定格式是否满足
 70         self.value = None #如果匹配成功值是多少
 71 
 72 
 73     def validate(self, name, input_value):
 74         """
 75         :param name:  字段名称
 76         :param input_value:  表单输入内容
 77         :return:
 78         """
 79         if not self.required:
 80             self.is_valid = True
 81             self.value = input_value
 82         else:
 83             if not input_value.strip():   #用户输入为空
 84                 if self.error_msg.get('required', None):  #得到错误信息
 85                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
 86                 else:
 87                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
 88             else:
 89                 ret = re.match(self.REGULAR, input_value)
 90                 if ret:  #如果匹配
 91                     self.is_valid = True
 92                     self.value = input_value
 93                 else:
 94                     if self.error_msg.get('valid', None):
 95                         self.error = self.error_msg['valid']
 96                     else:
 97                         self.error = "%s is invalid" % name
 98 
 99 
100 class CheckboxField:
101     #checkbox 验证没有值即可
102     def __init__(self, error_msg_dict=None, required=True):
103         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
104         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
105         if error_msg_dict:
106             self.error_msg.update(error_msg_dict)
107         self.required = required
108         self.error = None #错误信息
109         self.is_valid = False #判定格式是否满足
110         self.value = None #如果匹配成功值是多少
111 
112 
113     def validate(self, name, input_value):
114         """
115         :param name:  字段名称favor
116         :param input_value:  表单输入内容
117         :return:
118         """
119         print(name,input_value)
120         if not self.required:
121             self.is_valid = True
122             self.value = input_value
123         else:
124             if not input_value:   #用户输入为空
125                 if self.error_msg.get('required', None):  #得到错误信息
126                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
127                 else:
128                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
129             else:
130                 self.is_valid = True
131                 self.value = input_value
132                 print(name,self.value)
133 
134 
135 class FileField:
136     REGULAR = "^(\w+\.pdf)|(\w+\.mp3)|(\w+\.py)$"
137     #checkbox 验证没有值即可
138     def __init__(self, error_msg_dict=None, required=True):
139         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
140         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
141         if error_msg_dict:
142             self.error_msg.update(error_msg_dict)
143         self.required = required
144         self.error = None #错误信息
145         self.is_valid = True #判定格式是否满足
146         self.value = None #如果匹配成功值是多少
147         self.name = None
148         self.success_file_name_list  =[]
149 
150 
151     def validate(self, name, all_file_name_list):
152         """
153         :param name:  字段名称favor
154         :param all_file_name_list:  所有文件的文件名称
155         :return:
156         """
157         self.name = name
158         print(name,all_file_name_list)
159         if not self.required:
160             self.is_valid = True
161             self.success_file_name_list = all_file_name_list
162         else:
163 
164             for file_name in all_file_name_list:
165                 ret = re.match(FileField.REGULAR, file_name)
166                 if not ret:  # 如果bu 匹配
167                     self.is_valid = False
168                     print("aaaaaaaa",self.is_valid)
169                     if self.error_dict.get("valid",None):
170                         self.error = self.error_dict["valid"]
171                     else:
172                         self.error = "%s is invalid" % name
173                     break;
174 
175                 else:
176 
177                     self.success_file_name_list.append(file_name)
178 
179                     print("bbbbbbbbbb", self.is_valid)
180 
181                     self.value = self.success_file_name_list
182 
183 
184 
185     def save(self, request, path=None):
186         file_metas = request.files.get(self.name)  #name 指的是 fafafa
187         for meta in file_metas:
188             file_name = meta['filename']
189             new_file_name = os.path.join(path,file_name)
190             if file_name and file_name in self.value:
191 
192                 with open(new_file_name, 'wb') as up:
193                     up.write(meta['body'])
194 
195 
196 class IndexHandler(tornado.web.RequestHandler):
197     def get(self):
198         self.render("index.html")
199 
200     def post(self):
201         obj = IndexForm()
202         is_valid,value_dict = obj.check_valid(self)
203         print(is_valid)
204 
205         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
206 
207         self.write(dict)
208 
209 class HomeHandler(tornado.web.RequestHandler):
210     def get(self):
211         error_value_dict = {}
212         self.render("home.html",error_dict = error_value_dict)
213 
214     def post(self):
215         obj = HomeForm()
216         is_valid,success_value_dict,error_value_dict = obj.check_valid(self)
217         print('aabb',is_valid)
218         if is_valid:
219             for k,v in success_value_dict.items():
220                 print(k,v)
221 
222             obj.fafafa.save(self.request,'statics')
223         else:
224             for k,v in error_value_dict.items():
225                 print(k,v)
226 
227             self.render("home.html",error_dict = error_value_dict)
228 
229         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
230 
231 
232 
233 class BaseForm(object):
234     def check_valid(self, handle):
235         flag = True
236         value_dict = {}
237         error_message_dict ={}
238         success_value_dict = {}
239         # 获取当前类的属性字典
240         form_dict = self.__dict__
241         for key, regular in form_dict.items():
242             #key  ip
243             #handle HomeIndex...
244             #reguler:IPField(required =true)
245             #在homeform继承baseform的时候,传递的regular是一个IPFiled的对象
246             if type(regular) == CheckboxField:
247                 #传递过来的regular 是一个对象
248                 input_value = handle.get_arguments(key)
249 
250             if type(regular) == FileField:
251                 # 获得文件名称
252                 file_list = handle.request.files.get(key)
253                 print('file_list',file_list)
254                  #file list 结构 [{"body":xxxx,"filename":xxx}]
255 
256                 file_name_list = []
257                 for item in file_list:
258                     file_name_list.append(item["filename"])
259                     #对所有文件名称进行验证
260 
261                 input_value = file_name_list
262 
263             else:
264                 input_value = handle.get_argument(key)
265 
266             #IPFiled中进行验证
267             regular.validate(key,input_value)
268 
269             if regular.is_valid:
270                 success_value_dict[key]=regular.value
271 
272                 print('regular.value',regular.value)
273 
274             else:
275                 error_message_dict[key] = regular.error
276                 flag = False
277 
278 
279         for a,d in success_value_dict.items():
280             print(a,d)
281 
282         for a, d in error_message_dict.items():
283             print(a, d)
284 
285         return flag, success_value_dict,error_message_dict
286 
287 class IndexForm(BaseForm):
288     def __init__(self):
289         self.host = "(.*)"
290         self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
291         self.port = '(\d+)'
292         self.phone = '^1[3|4|5|8][0-9]\d{8}$'
293 
294 class HomeForm(BaseForm):
295     def __init__(self):
296         # self.ip = IPField(required=True,error_msg_dict = {"required":"不可为空","valid":"格式错误"})
297         # self.host = StringField(required=True)
298         # self.favor = CheckboxField(required=True)
299         self.fafafa = FileField(required=True)
300 
301 
302 settings = {
303     'template_path': 'views',
304     'static_path': 'statics',
305     'static_url_prefix': '/static/',
306     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
307     'login_url': '/login'
308 }
309 
310 application = tornado.web.Application([
311     (r"/index", IndexHandler),
312     (r"/home", HomeHandler),
313 ], **settings)
314 
315 if __name__ == "__main__":
316     application.listen(8880)
317     tornado.ioloop.IOLoop.instance().start()
文件上传
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 
  4 import tornado.ioloop
  5 import tornado.web
  6 from hashlib import sha1
  7 import os, time
  8 import re
  9 
 10 
 11 class IPField:
 12     #静态字段
 13     REGULAR = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
 14     def __init__(self, error_msg_dict=None, required=True):
 15         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 16         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
 17         if error_msg_dict:
 18             self.error_msg.update(error_msg_dict)
 19         self.required = required
 20         self.error = None #错误信息
 21         self.is_valid = False #判定格式是否满足
 22         self.value = None #如果匹配成功值是多少
 23 
 24 
 25     def validate(self, name, input_value):
 26         """
 27         :param name:  字段名称
 28         :param input_value:  表单输入内容
 29         :return:
 30         """
 31 
 32         print('ffffff',name,input_value)
 33         if not self.required:
 34             self.is_valid = True
 35             self.value = input_value
 36         else:
 37             if not input_value.strip():   #用户输入为空
 38                 if self.error_msg.get('required', None):  #得到错误信息
 39                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
 40                 else:
 41                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
 42             else:
 43                 ret = re.match(self.REGULAR, input_value)
 44                 if ret:  #如果匹配
 45                     self.is_valid = True
 46                     self.value = input_value
 47                     print("匹配",self.value)
 48 
 49 
 50                 else:
 51 
 52                     print("不匹配")
 53                     if self.error_msg.get('valid', None):
 54                         self.error = self.error_msg['valid']
 55                     else:
 56                         self.error = "%s is invalid" % name
 57 
 58 
 59 class StringField:
 60     #静态字段
 61     REGULAR = "^(.*)$"
 62     def __init__(self, error_msg_dict=None, required=True):
 63         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
 64         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
 65         if error_msg_dict:
 66             self.error_msg.update(error_msg_dict)
 67         self.required = required
 68         self.error = None #错误信息
 69         self.is_valid = False #判定格式是否满足
 70         self.value = None #如果匹配成功值是多少
 71 
 72 
 73     def validate(self, name, input_value):
 74         """
 75         :param name:  字段名称
 76         :param input_value:  表单输入内容
 77         :return:
 78         """
 79         if not self.required:
 80             self.is_valid = True
 81             self.value = input_value
 82         else:
 83             if not input_value.strip():   #用户输入为空
 84                 if self.error_msg.get('required', None):  #得到错误信息
 85                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
 86                 else:
 87                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
 88             else:
 89                 ret = re.match(self.REGULAR, input_value)
 90                 if ret:  #如果匹配
 91                     self.is_valid = True
 92                     self.value = input_value
 93                 else:
 94                     if self.error_msg.get('valid', None):
 95                         self.error = self.error_msg['valid']
 96                     else:
 97                         self.error = "%s is invalid" % name
 98 
 99 
100 class CheckboxField:
101     #checkbox 验证没有值即可
102     def __init__(self, error_msg_dict=None, required=True):
103         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
104         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
105         if error_msg_dict:
106             self.error_msg.update(error_msg_dict)
107         self.required = required
108         self.error = None #错误信息
109         self.is_valid = False #判定格式是否满足
110         self.value = None #如果匹配成功值是多少
111 
112 
113     def validate(self, name, input_value):
114         """
115         :param name:  字段名称favor
116         :param input_value:  表单输入内容
117         :return:
118         """
119         print(name,input_value)
120         if not self.required:
121             self.is_valid = True
122             self.value = input_value
123         else:
124             if not input_value:   #用户输入为空
125                 if self.error_msg.get('required', None):  #得到错误信息
126                     self.error = self.error_msg['required'] #如果不为空,用户传递的默认信息
127                 else:
128                     self.error = "%s is required" % name  #如果为空,使用系统的默认信息
129             else:
130                 self.is_valid = True
131                 self.value = input_value
132                 print(name,self.value)
133 
134 
135 class FileField:
136     REGULAR = "^(\w+\.pdf)|(\w+\.mp3)|(\w+\.py)$"
137     #checkbox 验证没有值即可
138     def __init__(self, error_msg_dict=None, required=True):
139         self.error_msg = {}  # {'required': 'IP不能为空', 'valid': 'IP格式错误'}
140         #如果用户传递的错误信息不给空,将用户的信息更新到字典中,否则使用默认的错误信息
141         if error_msg_dict:
142             self.error_msg.update(error_msg_dict)
143         self.required = required
144         self.error = None #错误信息
145         self.is_valid = True #判定格式是否满足
146         self.value = None #如果匹配成功值是多少
147         self.name = None
148         self.success_file_name_list  =[]
149 
150 
151     def validate(self, name, all_file_name_list):
152         """
153         :param name:  字段名称favor
154         :param all_file_name_list:  所有文件的文件名称
155         :return:
156         """
157         self.name = name
158         print(name,all_file_name_list)
159         if not self.required:
160             self.is_valid = True
161             self.success_file_name_list = all_file_name_list
162         else:
163 
164             for file_name in all_file_name_list:
165                 ret = re.match(FileField.REGULAR, file_name)
166                 if not ret:  # 如果bu 匹配
167                     self.is_valid = False
168                     print("aaaaaaaa",self.is_valid)
169                     if self.error_dict.get("valid",None):
170                         self.error = self.error_dict["valid"]
171                     else:
172                         self.error = "%s is invalid" % name
173                     break;
174 
175                 else:
176 
177                     self.success_file_name_list.append(file_name)
178 
179                     print("bbbbbbbbbb", self.is_valid)
180 
181                     self.value = self.success_file_name_list
182 
183 
184 
185     def save(self, request, path=None):
186         file_metas = request.files.get(self.name)  #name 指的是 fafafa
187         for meta in file_metas:
188             file_name = meta['filename']
189             new_file_name = os.path.join(path,file_name)
190             if file_name and file_name in self.value:
191 
192                 with open(new_file_name, 'wb') as up:
193                     up.write(meta['body'])
194 
195 
196 class IndexHandler(tornado.web.RequestHandler):
197     def get(self):
198         self.render("index.html")
199 
200     def post(self):
201         obj = IndexForm()
202         is_valid,value_dict = obj.check_valid(self)
203         print(is_valid)
204 
205         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
206 
207         self.write(dict)
208 
209 class HomeHandler(tornado.web.RequestHandler):
210     def get(self):
211         error_value_dict = {}
212         self.render("home.html",error_dict = error_value_dict)
213 
214     def post(self):
215         obj = HomeForm()
216         is_valid,success_value_dict,error_value_dict = obj.check_valid(self)
217         print('aabb',is_valid)
218         if is_valid:
219             for k,v in success_value_dict.items():
220                 print(k,v)
221 
222             obj.fafafa.save(self.request,'statics')
223         else:
224             for k,v in error_value_dict.items():
225                 print(k,v)
226 
227             self.render("home.html",error_dict = error_value_dict)
228 
229         #如果全部验证成功,将用胡俗人的数据全部放入到字典中
230 
231 
232 
233 class BaseForm(object):
234     def check_valid(self, handle):
235         flag = True
236         value_dict = {}
237         error_message_dict ={}
238         success_value_dict = {}
239         # 获取当前类的属性字典
240         form_dict = self.__dict__
241         for key, regular in form_dict.items():
242             #key  ip
243             #handle HomeIndex...
244             #reguler:IPField(required =true)
245             #在homeform继承baseform的时候,传递的regular是一个IPFiled的对象
246             if type(regular) == CheckboxField:
247                 #传递过来的regular 是一个对象
248                 input_value = handle.get_arguments(key)
249 
250             if type(regular) == FileField:
251                 # 获得文件名称
252                 file_list = handle.request.files.get(key)
253                 print('file_list',file_list)
254                  #file list 结构 [{"body":xxxx,"filename":xxx}]
255 
256                 file_name_list = []
257                 for item in file_list:
258                     file_name_list.append(item["filename"])
259                     #对所有文件名称进行验证
260 
261                 input_value = file_name_list
262 
263             else:
264                 input_value = handle.get_argument(key)
265 
266             #IPFiled中进行验证
267             regular.validate(key,input_value)
268 
269             if regular.is_valid:
270                 success_value_dict[key]=regular.value
271 
272                 print('regular.value',regular.value)
273 
274             else:
275                 error_message_dict[key] = regular.error
276                 flag = False
277 
278 
279         for a,d in success_value_dict.items():
280             print(a,d)
281 
282         for a, d in error_message_dict.items():
283             print(a, d)
284 
285         return flag, success_value_dict,error_message_dict
286 
287 class IndexForm(BaseForm):
288     def __init__(self):
289         self.host = "(.*)"
290         self.ip = "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$"
291         self.port = '(\d+)'
292         self.phone = '^1[3|4|5|8][0-9]\d{8}$'
293 
294 class HomeForm(BaseForm):
295     def __init__(self):
296         # self.ip = IPField(required=True,error_msg_dict = {"required":"不可为空","valid":"格式错误"})
297         # self.host = StringField(required=True)
298         # self.favor = CheckboxField(required=True)
299         self.fafafa = FileField(required=True)
300 
301 
302 settings = {
303     'template_path': 'views',
304     'static_path': 'statics',
305     'static_url_prefix': '/static/',
306     'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
307     'login_url': '/login'
308 }
309 
310 application = tornado.web.Application([
311     (r"/index", IndexHandler),
312     (r"/home", HomeHandler),
313 ], **settings)
314 
315 if __name__ == "__main__":
316     application.listen(8880)
317     tornado.ioloop.IOLoop.instance().start()
文件上传-保存

 

 

抽屉练习 

使用了bootstrap 控件实现了模态框体

内容包括登录、发帖

redirect('/index/') 跳转到index

  1 <!DOCTYPE html>
  2 <html>
  3 <head lang="en">
  4     <meta charset="UTF-8">
  5     <title>抽屉新热榜</title>
  6     <link rel="stylesheet" href="{{static_url('css/commons.css')}}" />
  7     <link rel="stylesheet" href="{{static_url('plugins/bootstrap/css/bootstrap.css')}}" />
  8 
  9 </head>
 10 <body>
 11 <div class="pg-header">
 12     <div class="w">
 13         <a class="logo" href="/"></a>
 14         <div class="act-menu">
 15             <a href="/all/hot/recent/1" class="tb active">全部</a>
 16             <a href="/all/hot/recent/1" class="tb">42区</a>
 17             <a href="/all/hot/recent/1" class="tb">段子</a>
 18             <a href="/all/hot/recent/1" class="tb">图片</a>
 19             <a href="/all/hot/recent/1" class="tb">挨踢1024</a>
 20             <a href="/all/hot/recent/1" class="tb">你问我答</a>
 21         </div>
 22         <div class="key-sera">
 23 
 24             <form action="/search/show" method="post" name="searchFrm2" id="searchFrm2">
 25                 <input type="text" class="search-txt-s" name="words" id="txtSearch2" autocomplete="off">
 26 
 27                 <a href="javascript:;" class="i" name="searchBtn_2" id="searchBtn_3"><span class="ico"></span></a>
 28                 <input type="hidden" value="1" id="page" name="page">
 29             </form>
 30 
 31         </div>
 32 
 33         <div class="action-nav">
 34             <a href="/show/flow/1" style="float:left;position:relative;" id="btnDtaiShw">动态
 35                 <b class="notice-num-title" id="Dtai-num-title" style="right: 3px; display: none;">
 36                     <em id="Dtai-em"></em>
 37                 </b>
 38             </a>
 39             <a href="javascript:;" id="btnNotShw" class="notice-box">通知
 40                 <b class="notice-num-title" id="notice-num-title" style="display: none;">
 41                     <em id="notice-em"></em>
 42                     <i>+</i>
 43                 </b>
 44             </a>
 45             {% if user_info["is_login"] %}
 46             <a href="/user/link/saved/1" id="loginUserNc" class="userPro-Box">
 47                 <img src="http://img2.chouti.com/CHOUTI_05B313F703D34646848BCC5571510683_W148H148=30x30).jpg" id="userProImg">
 48                 <span class="u-nick" id="userProNick">{{ user_info["username"] }}</span>
 49                 <em id="userProArr"></em>
 50             </a>
 51 
 52             {% else %}
 53             <a onclick="Login();"> 登录</a>
 54             <a> 注册</a>
 55             {% end %}
 56         </div>
 57         <div class="user-opr-box" id="userOprBox" style="left: 869px; display: none;">
 58             <a href="/user/link/saved/1" style="border-top:0;">我的新热榜</a>
 59             <a href="/profile">设置</a>
 60             <a class="logout" href="javascript:;">退出</a>
 61             <a href="http://www.chouti.com/cdu_45792645155" target="_blank" class="ie6-a">我的收藏</a>
 62         </div>
 63     </div>
 64 </div>
 65 
 66 
 67 
 68 
 69 <div class="pg-body">
 70 
 71     <div style="background-color: #eee;">
 72         <div class="w body-content">
 73             <div class="clearfix">
 74                 <div class="content-l" >
 75                     <div class="nav-top-area">
 76                         <div class="child-nav">
 77                             <!-- 当不是全部页面时 -->
 78                             <a href="/r/pic/hot/1" hidefocus="false" class="icons active hotbtn" id="hotts-nav-btn">最热</a>
 79                             <a href="/r/pic/new/1" hidefocus="false" class="newbtn" id="newest-nav-btn">最新</a>
 80                             <!-- 当是全部页面时 -->
 81                         </div>
 82                         <!-- 当是全部页面时 -->
 83                         <a href="javascript:void(0);" onclick="Publish();" class="publish-btn" id="publishBtn"  lang="pic">
 84                             <span class="ico n1"></span><span class="n2" >发布的</span>
 85                         </a>
 86 
 87 
 88 
 89                     </div>
 90 
 91 
 92                     <div class="content-list" id="content_list">
 93 
 94                         {% for new in new_list%}
 95 
 96                         <div class="item">
 97 
 98                             <div class="timeIntoPool">1458285240218000,1458288835879000</div>
 99 
100                             <div class="null-item"></div>
101 
102                             <div class="news-content" id="newsContent8118680">
103                                 <div class="part1">
104                                     <a href="http://wallstreetcn.com/node/232597" class="show-content" target="_blank" onmousedown="linksClickStat(8118680);">{{new["title"]}}</a>
105                                     <span class="content-source">-wallstreetcn.com</span>
106                                     <!-- 段子和谣言类别不显示类别名称 -->
107                                     <a href="/r/news/hot/1" class="n2"><span class="content-kind">42区</span></a>
108                                     <!-- 来源手机客户端 -->
109                                     <!-- 显示话题标签 -->
110                                 </div>
111                                 <!-- 显示摘要 -->
112                                 <div class="area-summary">
113                                     <span class="summary">{{new["content"]}}</span>
114                                 </div>
115                                 <div class="part2" share-pic="http://img2.chouti.com/CHOUTI_AD764B84163A4A8093C2BF54CEAA4AAB_W400H266.jpg" share-title="进入调整期?深圳二手房成交较年初锐减30%" share-summary="多家中介数据显示,深圳3月二手房成交量比1月下降超过30%,新房成交量同样出现下降。分析称,政策收紧预期较大程度上影响了市场成交,而业主方多看好后市,双方存在一定博弈。预计4月评估价调整政策落地后,二手房市场或进入短暂调整期。" share-linkid="8118680" share-subject="42区">
116                                     <a href="javascript:;" class="digg-a" title="推荐"><span class="hand-icon icon-digg"></span><b>7</b><i style="display:none">8118680</i></a>
117                                     <a href="javascript:;" class="discus-a" id="discus-a-8118680" lang="8118680" title=""><span class="hand-icon icon-discus"></span><b>4</b></a>
118                                     <a href="javascript:;" class="collect-a" id="collect-a-8118680" lang="8118680" title="加入私藏" destjid="cdu_45792645155" jid="chouti150326"><span class="hand-icon icon-collect"></span><b>私藏</b></a>
119                                     <span class="left time-into"><a class="time-a" href="/link/8118680" target="_blank"><b>1小时18分钟前</b></a><i>入热榜</i></span>
120                                     <!-- 分享各微博的按钮 -->
121 
122                                     <span class="share-site-to" style="visibility: hidden;"><i>分享到</i><span class="share-icon"><a class="icon-sina" id="icon-sina" title="分享到新浪微博" href="javascript:;" hidefocus="true"></a><a class="icon-douban" id="icon-douban" title="分享到豆瓣" href="javascript:;" hidefocus="true"></a><a class="icon-qqzone" id="icon-qqzone" title="分享到QQ空间" href="javascript:;" hidefocus="true"></a><a class="icon-tenxun" id="icon-tenxun" title="分享到腾讯微博" href="javascript:;" hidefocus="true"></a><a class="icon-renren" id="icon-renren" title="分享到人人网" href="javascript:;" hidefocus="true"></a><a class="share-none"> </a></span></span></div>
123                                 <!-- 评论区域 -->
124                             </div>
125 
126                         </div>
127 
128                         {% end %}
129                     </div>
130                 </div>
131                 <div class="content-r">
132 
133                 </div>
134             </div>
135         </div>
136     </div>
137 
138 </div>
139 
140 
141 <div class="modal fade" id="login" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
142   <div class="modal-dialog" role="document">
143     <div class="modal-content">
144       <div class="modal-header">
145         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
146         <h4 class="modal-title" id="exampleModalLabel">用户登录</h4>
147       </div>
148         <form action="/login/" method = "post">
149       <div class="modal-body">
150 
151           <div class="form-group">
152             <label class="control-label">用户名</label>
153             <input type="text" class="form-control"  name = "username">
154           </div>
155           <div class="form-group">
156             <label class="control-label">密码:</label>
157              <input type="password" class="form-control"  name = "pwd">
158           </div>
159 
160       </div>
161       <div class="modal-footer">
162         <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
163         <button type="submit" class="btn btn-primary">提交</button>
164       </div>
165 
166             </form>
167 
168 
169     </div>
170   </div>
171 </div>
172 
173 <div class="modal fade" id="pub" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
174   <div class="modal-dialog" role="document">
175     <div class="modal-content">
176       <div class="modal-header">
177         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
178         <h4 class="modal-title" id="exampleModalLabe2">发帖</h4>
179       </div>
180         <form action="/publish/" method = "post">
181       <div class="modal-body">
182 
183           <div class="form-group">
184             <label class="control-label">标题</label>
185             <input type="text" class="form-control"  name = "title">
186           </div>
187           <div class="form-group">
188             <label class="control-label">内容:</label>
189              <input type="input" class="form-control"  name = "content">
190           </div>
191 
192       </div>
193       <div class="modal-footer">
194         <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
195         <button type="submit" class="btn btn-primary">提交</button>
196       </div>
197 
198             </form>
199 
200 
201     </div>
202   </div>
203 </div>
204 
205 
206 <script src="{{static_url('js/jquery-2.1.4.min.js')}}"></script>
207 <script src="{{static_url('plugins/bootstrap/js/bootstrap.js')}}" ></script>
208 
209 <script>
210     $(function(){
211         $('#loginUserNc,#userOprBox').mouseover(function(){
212             $('#userOprBox').css('display', 'block');
213             $('#loginUserNc').addClass('active');
214         }).mouseout(function () {
215             $('#userOprBox').css('display', 'none');
216             $('#loginUserNc').removeClass('active');
217         })
218     });
219 
220 
221    function Login(){
222        console.log('aaaa');
223        $('#login').modal("show");
224 
225    }
226 
227     function Publish(){
228        console.log('aaaa');
229        $('#pub').modal("show");
230 
231    }
232 </script>
233 </body>
234 </html>
抽屉HTML
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import tornado.ioloop
 5 import tornado.web
 6 
 7 INPUT_IST = []
 8 USER_INFO = {"is_login":None}
 9 NEW_LIST = [
10     {"title":"new帖子1","content":"今日大雨"},
11 
12 ]
13 
14 class MainHandler(tornado.web.RequestHandler):
15     def get(self):
16         print("ok1")
17         self.render("index.html", list_info=[11, 22, 33])
18 
19 
20 
21 class LoginHandler(tornado.web.RequestHandler):
22     def get(self):
23         print("ok1")
24         self.render("index.html", list_info=[11, 22, 33])
25 
26     def post(self,*args,**kwargs):
27         user_name =  self.get_argument("username",None)
28         pwd = self.get_argument("pwd",None)
29 
30         if user_name == "yan" and pwd == "123":
31             USER_INFO["is_login"] = True;
32             USER_INFO["username"] = user_name;
33             USER_INFO["pwd"] = pwd
34         self.render("index.html",user_info = USER_INFO,new_list = NEW_LIST)
35 
36 
37 
38 class PublishHandler(tornado.web.RequestHandler):
39     def get(self):
40         print("ok1")
41         self.render("index.html", list_info=[11, 22, 33])
42 
43     def post(self,*args,**kwargs):
44 
45         if USER_INFO["is_login"]:
46             title=  self.get_argument("title",None);
47             content = self.get_argument("content",None)
48 
49             NEW_LIST.append({"title":title,"content":content})
50             print(NEW_LIST)
51         self.redirect("/index/")
52 
53 
54 class IndexHandler(tornado.web.RequestHandler):
55     def get(self,*args,**kwargs):
56         self.render("index.html",user_info = USER_INFO,new_list = NEW_LIST)
57 
58 settings = {
59     'template_path': 'tpl',
60     'static_path': 'static',
61     'static_url_prefix': '/static/',
62 }
63 application = tornado.web.Application([
64     (r"/index/", IndexHandler),
65     (r"/login/", LoginHandler),
66     (r"/publish/", PublishHandler),
67 ],**settings)
68 
69 if __name__ == "__main__":
70     application.listen(8888)
71     tornado.ioloop.IOLoop.instance().start()
app.py

 

posted @ 2016-08-20 16:32  咖啡茶  阅读(235)  评论(0)    收藏  举报