BLOG
Enjoy when you can, and endure when you must.
DEC 15, 2012/Django
Django的Context和RequestContext
    
t = Template('My name is {{ name }}.')
c = Context({'name': 'Stephane'})
t.render(c)

Django的模板渲染中,Context可以用来传递数据,一个Context是一系列变量和值的集合,它和Python的字典有点相似。

context在Django里表现为Context类,在django.template模块里。她的构造函数带有一个可选的参数:一个字典映射变量和它们的值。调用Template对象的render()方法并传递context来填充模板。

要注意到是:t.render(c)返回的值是一个Unicode对象,而不是普通的Python字符串。

再看下面这个视图:

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 the second view.'
    })
return t.render(c)

在view_1和view_2中,每个视图都给模板传入了三个相同的变量:app、user和ip_address,这显然增加了代码的冗余度,这时RequestContext就派上用场了,它是一个Context的子类。当在一系例模板中都需要明确指定一些相同的变量时,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)
    
def view_2(request):
    # ...
    t = loader.get_template('template2.html')
    c = RequestContext(request, {'message': 'I am the second view.'},
        processors=[custom_proc])
    return t.render(c)

这是不是省事多了呢?

在settings.py中有一个与RequestContext密切相关的配置项为TEMPLATE_CONTEXT_PROCESSORS:

TEMPLATE_CONTEXT_PROCESSORS = (

   'django.core.context_processors.auth',

   'django.core.context_processors.debug',

   'django.core.context_processors.i18n',

   'django.core.context_processors.media',

)

这些Processors都会被RequestContext顺序调用,往当前Context中放入一些预定义变量。例如'django.core.context_processors.auth'作用在于默认向模板传递user、messages、perms等变量,分别描述当前登录用户、当前登录用户的消息列表和当前登录用户的权限。最后一点,当使用render_to_response方法时,RequestContext应作为其第三个参数传入,如:

    # ...
    return render_to_response('template.html', particular_data_dictionary,
        context_instance=RequestContext(request))

更多内容可以参考《The Django Book》(以上文章的部分内容和代码也截取自这里)或官方文档。

COMMENTS
23/09From EthanCui

不错不错

23/12From wenyuejie

很有用,谢谢!

LEAVE COMMNT