tornado 路由、模板语言、session

一:tornado路由系统:

1、面向资源编程:

场景:当我们给别人提供api的时候,往往提供url。比如:电影票api:

1 http://movie.jd.com/book_ticket:预订电影票。
2 http://movie.jd.com/get_ticket:获取电影票。
3 http://movie.jd.com/del_ticket:退电影票。

 如果我们给别人提供如上url api的话,那么我们和使用接口方的人需要维护这几个url。相应的成本较高。

因为如上的原因,有人根据url(统一资源定位符)提出设想:

我们是否可以根据用户的请求的method来给用户不同的服务呢?

for example:

1 def get(*arg):
2     pass  #查询电影票
3 def post(*arg):
4     passs #订购电影票
5 def  put(*arg):
6     pass#退电影票。

根据方法的不同,处理不同的功能。这种提供api方式我们叫做面向资源编程。也叫做restulful(Representational State Transfer缩写,表现层状态转化:http://www.ruanyifeng.com/blog/2011/09/restful)

tornado 天生支持restulful。根据用户的请求的不同,触发不同的函数。以后再给别人提供接口或者在使用别人的接口的时候,需要使用这种面向资源的方式。

2、2级域名,tornado在url划分的时候,比django更加友好,django是在主域名后面接着2级域名比如:http://www.liumeide.com:8888/cmdb/index 配置使用include 进行业务分类url。

而tornado直接使用二级域名来区分不同的业务:http://cmd.liumeide.com:8888/index cmdb服务,http://www.liumeide.com:8888/index  主站服务。http://monitor.liumeide.com:8888/index  监控服务。

京东也是这么区分,只不过京东各个系统是相对独立的。

主站:

团购:

配置:

1 application.add_handlers("cmd.liumeide.com",#重新设置url使用add_handlers方法,第一个参数是2级域名名称,后面是url列表。
2     [
3         (r"/index", CmdbHandler)
4     ]

完整代码:

 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("mian web")
11 class CmdbHandler(tornado.web.RequestHandler):
12     def get(self):
13         # self.write("Hello, world")
14         self.write('cmdb')
15 setting={
16     'template_path':'template',#设置模板文件路径。
17     'static_path':'static'#设置静态资源路径
18 }
19 application = tornado.web.Application([
20     (r"/index", MainHandler),
21 ],**setting)
22 application.add_handlers("cmd.liumeide.com",#重新设置url使用add_handlers方法,第一个参数是2级域名名称,后面是url列表。
23     [
24         (r"/index", CmdbHandler)
25     ]
26 )
27 
28 if __name__ == "__main__":
29     application.listen(8888)
30     tornado.ioloop.IOLoop.instance().start()

 note:

  1. 他们公用一个setting配置。!!!

 效果:

二:模板语言:

在模板语言中,for循环支持break、continue等语法,语法形式:{%break%} 也支持python的一些方法.比如lenth等。

也支持母板和子板,只是结束符是end 而不是 endblock。

 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> 

子板:

 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 

导入:也有页面的导入

header.html

1 <div>
2     <ul>
3         <li>1024</li>
4         <li>42区</li>
5     </ul>
6 </div>
7 
8 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 

自定制功能:uimethod和uimodlues。

对比:

  • 2者都可以给前端传递参数,不过method只能传递方法函数,而uimodules传递是类,通过类定义不同的方法,前端调用不方法函数。
  • uimodules可以给前端传递js、css等。

uimethod:

首先需要定义个模块比如:co.py. 然后写方法:

1 def f1(self,a):
2     return a

在配置setting中注册:

1 import  co
2 setting={
3     'template_path':'template',#设置模板文件路径。
4     'static_path':'static',#设置静态资源路径
5     'ui_methods':co,#注册
6 } 

后台代码:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import tornado.ioloop
 5 import tornado.web
 6 import  co
 7 
 8 class MainHandler(tornado.web.RequestHandler):
 9     def get(self):
10         self.render('main.html')
11 setting={
12     'template_path':'template',#设置模板文件路径。
13     'static_path':'static',#设置静态资源路径
14     'ui_methods':co,
15 }
16 application = tornado.web.Application([
17     (r"/index", MainHandler),
18 ],**setting)
19 
20 if __name__ == "__main__":
21     application.listen(8888)
22     tornado.ioloop.IOLoop.instance().start()

前端页面引用:注意是2个大括号类似于变量的引用。

1 <h1> {{f1(2)}}</h1>

效果:

uimodles:

1、定义模块文件:oc.py

2:写类和方法。

 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 
 8     def render(self, *args, **kwargs):
 9         return '<h1> 2</h1>'
10     def javascript_files(self):
11         return 'http://111.js'
12     def css_files(self):
13         return 'http://222.css'

3:前端注册

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 import tornado.ioloop
 5 import tornado.web
 6 import  co
 7 import oc
 8 class MainHandler(tornado.web.RequestHandler):
 9     def get(self):
10         self.render('main.html')
11 setting={
12     'template_path':'template',#设置模板文件路径。
13     'static_path':'static',#设置静态资源路径
14     'ui_methods':co,
15     'ui_modules':oc,
16 }
17 application = tornado.web.Application([
18     (r"/index", MainHandler),
19 ],**setting)
20 
21 if __name__ == "__main__":
22     application.listen(8888)
23     tornado.ioloop.IOLoop.instance().start()

4:页面引用:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 <h1> {{f1(2)}}</h1>
 9 {% module  custom(22) %}<!--注意页面的引用方式不一样uimodule是需要关键字module 以及百分号和uimethod的不同-->
10 </body>
11 </html>

效果:

三:tornado session

设计思想:

  • 服务器端产生随机字符串并写入客户端,下次客户端请求的时候携带这个随机字符串。
  • 服务器端需要储存该随机字符串,并额外保存用户其他信息,比如:用户名。
  • 客户端每次请求,需要判断客户端是否有已经写入cookie。
  • 每次访问,更新cookie过期时间。而不是每次都写入随机字符串。
  • session信息可以存储在内存、数据库、redis等。设置过期时间,定期清理,释放磁盘空间。
  • 对于伪造的cookie,重新写入客户端。
  • 随机字符串可以用time来生成md5写入客户端。

代码实现:

 1 #!/usr/bin/env python
 2 #-*-coding:utf-8-*-
 3 # author:liumeide
 4 import hashlib
 5 import time
 6 Session_Info={}
 7 
 8 def md5():
 9     m = hashlib.md5()
10     m.update(bytes(str(time.time()),encoding='utf-8'))
11     return m.hexdigest()
12 
13 class Session:
14     def __init__(self,handler):
15         self.handler=handler
16     def check_se(self):
17         current_time = time.time()
18         ret = self.handler.get_cookie('cookie_str', None)  # 自定义cookie key值。下次访问的请求的时候根据这个key来获取cookie的随机字符串。
19         if ret:  # 在有效的cookie设置范围内。
20             if ret in Session_Info.keys():  # 合法的cookie
21                 cookie_str = ret
22                 return True
23             else:  # 非法伪造或者过期的cookie。
24                 cookie_str = md5()
25         else:  # 第一次访问请求设置cookie
26             cookie_str = md5()
27             Session_Info[cookie_str] = {}
28             self.handler('cookie_str', cookie_str, expires=current_time + 200)  # 无论你是第一次还是多次请求,cookie都需要重新写入浏览器。需要设置过期时间。
29 
30     def __getitem__(self, item):#获取cookie
31         pass
32     def __setitem__(self, key, value):#设置cookie
33         pass
34     def __delitem__(self, key):#删除ookie
35         pass
原文地址:https://www.cnblogs.com/evilliu/p/5992286.html