Django------The template 模版高级进阶1 2012.08.30

        Context 是一个传递给模版的名称到值的映射,类似python字典。

        模版渲染就是通过从context获取值来替换模版中变量并执行所有的模版标签。

        RequestContext默认的在模版context中加入了一些变量,如HttpRequest对象或当前登陆用户的相关信息。当你不想在一系列模版中都明确指定一些相同的变量时,应该使用RequestContext。例如考虑下面两个图:

        

from django.template import loader, Context

def view_1(request):
    ..........
    t = loader.get_template('template1.html')
    c = Context({
        'app':'My app',
        'user': request.user,
        'ip_address': request.META['REMOTE_ADDR'],
        'message': 'I am view 1.'
    })
    return t.render(c)
def view_2(request):
    .........
     t = loader.get_template('template2.html')
     c= Context({
        'app': 'My app',
        'user' : request.user,
        'ip_address': request.META['REMOTE_ADDR'],
        'message': 'I am view.   
})
return t.render(c)

我们故意不使用render_to_response() 这个快捷方法,手动的载入模版,手动构造context对象然后渲染模版,为了说清步骤。

每个视图中都给模版传入了三个相同的变量:app user ip_address, 怎么去掉这些冗余。

最直接的方法是用context处理器来处理与处理器并传递给RequestContext.改写如下:

from django.template import loader, RequestContext

def custom_proc(request):
        "A context processor that provides 'app', 'user' and 'ip_address'."
        return{'app' :'my_app',
                    'user':request.user,
                    'ip_address': request.META['REMOTE_ADDR']
       }

def view_1(request):
        t = loader.get_template('template1.html')
        c = RequestContext(request, {'message':'I am view 1.'},
                 processors=[custom_proc])
        return t.render(c)

        我们定义的custom_prom是一个context处理器,它接收一个HttpResponse对象,然后返回一个字典,这个字典中包含了可以在模版context中使用的变量。

        使用RequestContext代替了Context。有两种不同点:RequestContext的第一个参数需要传递一个HttpResponse对象,有一个可选的参数processors,这是一个包含context处理器函数的列表或者元组,在这里,我们传递了我们之前定义的处理器函数custom_proc。

        函数custom_proc提供了几个变量。每个视图仍然具有很大的灵活性,可以引入我们需要的任何模版变量。

        之前我们都用render_to_response来代替调用loader.get_template(),然后创建一个context对象,最后再调用render()过程。底层的工作就是上边的例子。建议选择render_to_response作为context的处理器,这个时候用到:context_instance参数:

from django.shortcuts import render_to_response
from django.template import RequestContext

def custom_proc(request):
        " A context processor that provides 'app', 'users', and 'ip_address'."
           return {
        'app': 'My app',
        'user': request.user,
        'ip_address': request.META['REMOTE_ADDR']
    }

def view_1(request):
    # ...
    return render_to_response('template1.html',
        {'message': 'I am view 1.'},
        context_instance=RequestContext(request, processors=[custom_proc]))

def view_2(request):
    # ...
    return render_to_response('template2.html',
        {'message': 'I am the second view.'},
        context_instance=RequestContext(request, processors=[custom_proc]))

这里我们将每个视图的模版渲染代码写成了一行代码。

虽然这是一种改进,但是,请考虑一下这段代码的简洁性,我们现在不得不承认的是在 另外 一方面有些过分了。 我们以代码冗余(在 processors 调用中)的代价消除了数据上的冗余(我们的模板变量)。 由于你不得不一直键入 processors ,所以使用context处理器并没有减少太多的输入量。

django因此提供了全剧变量context处理器的支持,TEMPLATE_CONTEXT_PEOCESSORS指定了哪些context processors总是默认使用的,这样就省去了每次使用RequestContext都指定processors的麻烦,默认情况是:

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
)

这个设置项是一个可调用函数的元组,其中的每个函数使用了和上文中我们的 custom_proc 相同的接口,它们以request对象作为参数,返回一个会被合并传给context的字典: 接收一个request对象作为参数,返回一个包含了将被合并到context中的项的字典。 

每个处理器将会按照顺序应用。 也就是说如果你在第一个处理器里面向context添加了一个变量,而第二个处理器添加了同样名字的变量,那么第二个将会覆盖第一个。

Django提供了几个简单的context处理器,有些在默认情况下被启用的。

 

posted @ 2012-08-30 20:52  事件轮询,回不到过去  阅读(299)  评论(0编辑  收藏  举报