Django学习笔记(13):模板进阶

一、关于Django模板

之前洋洋洒洒写了一篇Django模板,但是“手➹”不小心给删除了。。。。今天重写一篇,就相当于总结。

---------------------------

注意:始终要知道模板template是Django提供的机制,里面有模板变量和模板标签,仅此而已!它解决在视图中HTML硬编码的问题,模板 是一个纯文本文件,或是一个用Django模板语言标记过的普通的Python字符串。

二、template模块

1 >>> from django import template #导入模板

1、创建模板对象
Template 类就在 django.template 模块中,构造函数接受一个参数。如:

1 t = template.Template('My name is {{ name }}.')

创建一个 Template 对象,模板系统在内部编译这个模板到内部格式,并做优化,做好 渲染的准备。
注意:如果模板语法有错误,那么在调用 Template() 时就会抛出 TemplateSyntaxError 异常

2、模板渲染
渲染 就是是通过从context获取值来替换模板中变量并执行所有的模板标签。
一旦创建一个 Template 对象,你可以用 context 来传递数据给它。 一个context是一系列变量和它们值的集合,类似字典Context 类在 django.template 模块里,她的构造函数带有一个可选的参数: 一个字典映射变量和它们的值。
调用 Template 对象 的 render() 方法并传递context来填充模板:

Django学习笔记(13):模板进阶

注意t.render(c)返回的值是一个Unicode对象,不是普通的Python字符串。 可以通过字符串前的u来区分。 在框架中,Django会一直使用Unicode对象而不是普通的字符串。

当然,同一模板,还可以有多个上下文(即context)

3.句点查找规则:

1):字典类型查找 (比如 foo["bar"] )
2):属性查找 (比如 foo.bar )
3):方法调用 (比如 foo.bar()
4):列表类型索引查找 (比如 foo[bar] )
如:

1 #用于访问列表索引

2 >>> from django.template import Template, Context

3 >>> t = Template('Item 2 is {{ items.2 }}.')

4 >>> c = Context({'items': ['apples', 'bananas', 'carrots']})

5 >>> t.render(c)

6 u'Item 2 is carrots.'

三、在视图中使用

参见:
Django学习笔记(4):Django模板系统(上)
Django学习笔记(5):Django模板系统(下)

 四、RequestContext和Context处理器

from django.template import Context,RequestContext

 RequestContext 默认地在模板context中加入了一些变量,如 HttpRequest 对象或当前登录用户的相关信息。

demo:

URL:

urlpatterns = patterns('',

    (r'^test1/$','demo.views.t1'), 

    (r'^test2/$','demo.views.t2'),        

)

 使用Context和RequestContext区别,注意注释掉的部分是属于Context的,这里视图冗余,故使用RequestContext

#coding=utf-8

from django.http import HttpRequest,HttpResponse,HttpResponseRedirect

from django.template import TemplateDoesNotExist,RequestContext,loader,Context,Template



def custom_pro(request):

    '''app、user、IP'''

    return{

       'app':'My app',

       'user':request.user,

       'ip':request.META['REMOTE_ADDR']

    }

    

def custom_other_pro(request):

    '''name,age,job'''

    return{

       'name':'BeginMan',

       'age':22,

       'job':'Pythoner'       

    }

    

def t1(request):

    t=loader.get_template('test/t1.html')

#    c=Context({'app':'My app',

#               'user':request.user,

#               'ip':request.META['REMOTE_ADDR'],

#               'message':'i am t1'})

    c=RequestContext(request,{'message':'i am t1'},processors=[custom_pro])

    return HttpResponse(t.render(c))



def t2(request):

    t=loader.get_template('test/t2.html')

#    c=Context({'app':'My app',

#               'user':request.user,

#               'ip':request.META['REMOTE_ADDR'],

#               'message':'i am t2'})

    c=RequestContext(request,{'message':'i am t2'},processors=(custom_pro,custom_other_pro))#元祖形式也行

    return HttpResponse(t.render(c))

 当然。也可以进行数据处理:

def custom_Msg(request):

    '''return Msg data'''

    msg=Msg.objects.all()

    return{'msg':msg}

 分析:

1):定义custom_pro、custom_other_pro custom_Msg这些函数,其实都是context处理器,它接收一个 HttpRequest 对象,然后返回一个字典,这个字典中包含了可以在模板context中使用的变量。 它就做了这么多。

2):我们在这两个视图函数中用 RequestContext 代替了 Context 。在context对象的构建上有两个不同点。 一, RequestContext 的第一个参数需要传递一个 HttpRequest 对象,就是传递给视图函数的第一个参数( request )。二, RequestContext 有一个可选的参数 processors(处理器的意思) ,这是一个包含context处理器函数的列表或者元组。 在这里,我们传递了我们之前定义的处理器函数 custom_pro、custom_other_pro custom_Msg

3):如果还不明白,可以看看RequestContext的源码:

源码:

class RequestContext(Context):

    """

    This subclass of template.Context automatically populates itself using

    the processors defined in TEMPLATE_CONTEXT_PROCESSORS.

    Additional processors can be specified as a list of callables

    using the "processors" keyword argument.

    """

    def __init__(self, request, dict=None, processors=None, current_app=None):

        Context.__init__(self, dict, current_app=current_app)

        if processors is None:

            processors = ()

        else:

            processors = tuple(processors)

        for processor in get_standard_processors() + processors:

            self.update(processor(request))

 接下来就开始处理模板了,这里列出了t2.html:

-------custom_pro<br>

<div style="color:Red">

{{app}}<br>

{{user}}<br>

{{ip}}<br>

{{message}}<br>

</div>



-------custom_other_pro<br>

<div style="color:Blue">

{{name}}<br>

{{age}}<br>

{{job}}

</div>



<div style="color:#CCC">

{% for obj in msg %}

<li>{{obj.title}}</li>

{% endfor %}

</div>

 效果如下:
Django学习笔记(13):模板进阶

扩展:

render_to_response() 这个快捷方式,它可以简化调用 loader.get_template(),但是上面为了说明两者之间的区别,没有使用,这里我们还是要使用render_to_response(),此时要加入context_instance参数才能正常使用:

def t2(request):

    return render_to_response(

        'test/t2.html',

        {'message':'t2'},

        context_instance=RequestContext(request,processors=(custom_pro,custom_other_pro,custom_Msg)))

#    t=loader.get_template('test/t2.html')

#    c=RequestContext(request,{'message':'i am t2'},processors=(custom_pro,custom_other_pro,custom_Msg))

#    return HttpResponse(t.render(c))

 五、全局 context处理器

Django提供对 全局 context处理器的支持。 TEMPLATE_CONTEXT_PROCESSORS 指定了哪些context processors总是默认被使用。这样就省去了每次使用 RequestContext 都指定 processors 的麻烦。

默认情况下, 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',

)

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

具体分析见下节

你可能感兴趣的:(django)