Tornado Web 开发 框架搭建 (2)

模板设置

由于tornado自带自己的模板,要把jinja2引入tornado需要做一些特殊处理

在这里,新建jinja.py 参考https://github.com/mxyzm/snail/blob/master/joiners/jinja.py


?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#coding=utf-8
"""Make Jinja2 work with Tornado."""
 
from tornado import escape
 
from jinja2 import Environment, FileSystemLoader
 
 
class JinjaApplicationMixin( object ):
     def __init__( self , * args, * * settings):
         super (JinjaApplicationMixin, self ).__init__( * args, * * settings)
         if "template_path" not in settings:
             return
         if "template_loader" in settings:
             loader = settings[ 'template_loader' ]
         else :
             loader = FileSystemLoader(settings[ 'template_path' ])
         if "debug" in settings:
             auto_reload = settings[ "debug" ]
         else :
             auto_reload = False
         autoescape = bool (settings.get( 'autoescape' , False ))
         self .jinja_env = Environment(
             loader = loader,
             auto_reload = auto_reload,
             autoescape = autoescape, )
 
 
class JinjaHandlerMixin( object ):
     def render_string( self , template_name, * * context):
         self .require_setting( "template_path" , "render" )
         default_context = {
             'handler' : self ,
             'request' : self .request,
             'current_user' : self .current_user,
             'static_url' : self .static_url,
             'xsrf_form_html' : self .xsrf_form_html,
             'reverse_url' : self .reverse_url,
             'me' : self .oUser,
         }
         escape_context = {
             'escape' : escape.xhtml_escape,
             'xhtml_escape' : escape.xhtml_escape,
             'url_escape' : escape.url_escape,
             'json_encode' : escape.json_encode,
             'squeeze' : escape.squeeze,
             'linkify' : escape.linkify,
         }
         context.update(default_context)
         context.update(escape_context)
         context.update( self .ui) # Enabled tornado UI modules and methods.
         template = self .application.jinja_env.get_template(
             template_name)
         return template.render( * * context)

这里我加了个当前用户对象me 给前台使用

然后主Application使用Mixin 继承 JinjaApplicationMixin

?

1
2
class MainApplication(JinjaApplicationMixin, tornado.web.Application):
     pass

server.py 里面就可以这样跑

?

1
2
3
4
application = MainApplication(make_handlers(URL_PREFIX,
                                             (r '/' , include( 'handlers.index' )),
                                             (r '/' , include( 'handlers.user' )),
                                             (r '/' , include( 'handlers.userGroup' )),

BaseHandler 同Mixin JinjaHandlerMixin

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class BaseHandler(JinjaHandlerMixin, tornado.web.RequestHandler):
     def get_current_user( self ):
         user = self .get_secure_cookie( "user" )
         if user is not None :
             self .oUser = self .session.query(User).filter_by(name = user).first()
         return user
 
     def initialize( self ):
         self .session = db_session
         self .oUser = None
 
 
     def on_finish( self ):
         self .session.close()

这里已经为Sqlalchemy的session处理和 tornado的用户登录验证打好基础,等以后再做说明。

然后在handler里面使用:

?

1
2
3
4
5
6
@route (' ', name=' index')
class IndexHandler(BaseHandler):
     @tornado .web.authenticated
     @tornado .web.asynchronous
     def get( self ):
         self .render( "index.html" )

注意:

  1. JinjaHandlerMixin里面的context是可以自己修改和添加的

  2. 在做BaseHandler的多继承的时候,一定要把mixin的放在前面,RequestHandler放后面

在server.py里面做下template_path 的配置
然后,在主页面里面就可以按jinja2的方式写模板了。理论上说,tornado的UI模块也能一起使用,但是个人觉得jinja2 的macro 也同样能实现相应功能,这里就没做测试。

下面是登录窗口的示例

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{ % extends "base.html" % }
{ % block title % }登陆{ % endblock % }
{ % block css % }
<style type = "text/css" >
     body {
         padding - top: 40px ;
         padding - bottom: 40px ;
         background - color: #eee;
     }
 
     .form - signin {
         max - width: 330px ;
         padding: 15px ;
         margin: 0 auto;
     }
 
     .form - signin .form - signin - heading,
     .form - signin .checkbox {
         margin - bottom: 10px ;
     }
 
     .form - signin .checkbox {
         font - weight: normal;
     }
 
     .form - signin .form - control {
         position: relative;
         font - size: 16px ;
         height: auto;
         padding: 10px ;
         - webkit - box - sizing: border - box;
         - moz - box - sizing: border - box;
         box - sizing: border - box;
     }
 
     .form - signin .form - control:focus {
         z - index: 2 ;
     }
 
     .form - signin input [ type = "text" ] {
         margin - bottom: - 1px ;
         border - bottom - left - radius: 0 ;
         border - bottom - right - radius: 0 ;
     }
 
     .form - signin input [ type = "password" ] {
         margin - bottom: 10px ;
         border - top - left - radius: 0 ;
         border - top - right - radius: 0 ;
     }
< / style>
{ % endblock % }
{ % block body % }
<div class = "container" >
     <form class = "form-signin" method = "post" >
         {{ xsrf_form_html() }}
         <h2 class = "form-signin-heading" >登录< / h2>
         < input name = "name" type = "text" class = "form-control" placeholder = "用户名" autofocus>
         < input name = "pwd" type = "password" class = "form-control" placeholder = "密码" >
         { % if form|d(none) is not none % }
         <div class = "alert alert-danger" >
             {{ form.mainerr}}
         < / div>
         { % endif % }
         <label class = "checkbox" >
             < input name = "remember" type = "checkbox" value = "remember" >记住我
         < / label>
         <button class = "btn btn-lg btn-primary btn-block" type = "submit" >登录< / button>
     < / form>
 
< / div> <! - - / container - - >
{ % endblock % }

静态文件通常如下使用:

?

1
<link href = "{{ static_url(" css / bootstrap. min .css ") }}" rel = "stylesheet" media = "screen" >

需要在 server.py里面配置下  static_path


你可能感兴趣的:(Tornado Web 开发 框架搭建 (2))