• 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
  • 相关阅读:
    1137 Final Grading (25 分)
    1136 A Delayed Palindrome (20 分)
    1135 Is It A Red-Black Tree (30 分)
    1134 Vertex Cover (25 分)
    1133 Splitting A Linked List (25 分)
    1074 Reversing Linked List (25 分)
    1132 Cut Integer (20 分)
    HDU 3342 Legal or Not
    IDEA解决JSP页面无法使用EL表达式问题
    25. Bootstreap 下拉菜单
  • 原文地址:https://www.cnblogs.com/evilliu/p/5992286.html
Copyright © 2020-2023  润新知