django template

一、模板基本元素

  1、例子程序

    1)urls.py中新增部分

from django.conf.urls import patterns, url, include

urlpatterns = patterns('',
                      #...
                      (r'^template_use/$', 'django_web_app.views.template_use'),
)

    2)views.py中新增部分

def template_use(request):
    person_name='jimfeng'
    company='fuyoo'
    ship_date=datetime.datetime.now()
    item_list=[]
    item_list[0:0] = ['aaa']
    item_list[0:0] = ['bbb']
    item_list[0:0] = ['ccc']
    item_list.reverse();
    ordered_warranty=True

    dic = {'person_name':person_name, 'company':company,'ship_date':ship_date,
           'item_list':item_list,'ordered_warranty':ordered_warranty}
return render_to_response('template_use.html', dic)

    3)template_use.html

<html>
<head><title>Ordering notice</title></head>

<body>

<h1>Ordering notice</h1>

<p>Dear {{ person_name }},</p>

<p>Thanks for placing an order from {{ company }}. It's scheduled to
ship on {{ ship_date|date:"F j, Y" }}.</p>

<p>Here are the items you've ordered:</p>

<ul>
{% for item in item_list %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

{% if ordered_warranty %}
    <p>Your warranty information will be included in the packaging.</p>
{% else %}
    <p>You didn't order a warranty, so you're on your own when
    the products inevitably stop working.</p>
{% endif %}

<p>Sincerely,<br />{{ company }}</p>

</body>
</html>

   4)运行结果:

    

  2、基本元素

   1)变量

      {{变量名}}

     eg:{{ person_name }}

   2)标签

      {%标签名  变量名%}或{%标签名%}

     eg:

{% if ordered_warranty %}
   #.....
{% else %}
   #.....
{% endif %}

    3)过滤器

    {{变量名|过滤器名:过滤器参数}}

    eg:{{ ship_date|date:"F j, Y" }}

   django模板标签,过滤器的详细参考:

        http://djangobook.py3k.cn/appendixF/

  3、独立的python代码中使用django模板系统

    步骤:a)创建template对象

       b)创建contex对象

       c)调用模板对象的render()方法,将template中的变量替换为context中的值。

    1)简单的模板渲染:   

def template_use(request):
    #创建模板
    t = template.Template('My name is {{ name }},   ship_date is {{ship_date}}')
    #创建context
    c = template.Context({'name': '普罗米小斯',
                          'ship_date': datetime.date(2009, 4, 2)
                        })
    #template调用render方法,将变量替换为context传进来的值
    info_str=t.render(c)#返回的是unicode对象,而不是普通字符串

    html = "<html><body>info_str: %s.</body></html>" % info_str
    return HttpResponse(html)

    运行结果:

    

   2)较复杂的模板渲染

def template_use(request):
    #创建模板
    #三个引号来标识文本,这样可以包含多行
    raw_template = """<p>Dear {{ person_name }},</p>
    <p>Thanks for placing an order from {{ company }}. It's scheduled to
    ship on {{ ship_date|date:"F j, Y" }}.</p>

    {% if ordered_warranty %}
    <p>Your warranty information will be included in the packaging.</p>
    {% else %}
    <p>You didn't order a warranty, so you're on your own when
    the products inevitably stop working.</p>
    {% endif %}

    <p>Sincerely,<br />{{ company }}</p>"""
    t = template.Template(raw_template)
    #创建context
    c = template.Context({'person_name': '普罗米小斯',
                          'company': 'Fuyoo',
                          'ship_date': datetime.date(2009, 4, 2),
                          'ordered_warranty': False
                        })
    #template调用render方法,将变量替换为context传进来的值
    info_str=t.render(c)#返回的是unicode对象,而不是普通字符串

    html = "<html><body>info_str: %s.</body></html>" % info_str
    return HttpResponse(html)

   运行结果:

   

   3)1个template多个context分别渲染的常用方式

def template_use(request):
    t = template.Template('Hello, {{ name }}')#只需创建一次template

    name_list=('John', 'Julie', 'Pat')
    for name in name_list:
        info_str=t.render(template.Context({'name': name}))
        print info_str

    html = "<html><body>info_str:</body></html>"
    return HttpResponse(html)

    运行结果:(控制台输出)

   

二、模板常用功能

  1、Context传递不同类型参数,template的对应访问方式

class Person(object):
    def __init__(self, name, age):
        self.name,self.age = name,age

def template_use(request):
    #字典对象作为context传递的参数,template访问字典的"键"
    t_dic = template.Template('用户名:{{ person.name }},年龄:{{person.age}}')
    person_dic = {'name': 'Sally', 'age': 43}
    person_info_dic=t_dic.render(template.Context({'person': person_dic}))
    print person_info_dic

    #自定义类的对象作为context传递的参数,template访问对象属性
    t_class = template.Template('用户名:{{ person.name }},年龄:{{person.age}}')
    person_class =Person('aaa',22)
    person_info_class=t_class.render(template.Context({'person': person_class}))
    print person_info_class

    #对象作为context传递的参数,template调用对象的方法
    t_class_method=template.Template('原始字符串:{{info_str}}, 大写字符串:{{info_str.upper}}')
    output_info=t_class_method.render(template.Context({'info_str': 'hello'}))
    print output_info

    #列表作为context传递的参数,template访问列表索引号
    t_list=template.Template('索引号为2的用户名:{{name_list.2}}')
    name_list=['name000','name001','name002','name003','name004']
    output_info=t_list.render(template.Context({'name_list':name_list}))
    print output_info

    html = "<html><body>info_str:</body></html>"
    return HttpResponse(html)

   运行结果:

   

   2、Context中参数的增、删

def template_use(request):
    c=template.Context({
                'name000':'aaa',
                'name001':'bbb',
                'name002':'ccc'
    })

    del c['name001']
    c['name003'] = 'ddd'

    for item in c:
        print item

    html = "<html><body>info_str:</body></html>"
    return HttpResponse(html)

    运行结果:

    

   3、模板中的常用标签

    1)if/else标签中的布尔值

       所有为False的情形:

        a)空列表:[]

        b)空元组:()

        c)空字典:{}

        d)空字符串:''

        e)零值:0

        f)对象为none

       除以上情况外均为True

       eg:

{% if not athlete_list or is_no_coach %}
    <p>没有运动员或者没有教练</p>
{% else %}
    <p>既有运动员又有教练</p>
{% endif %}

    2)for标签
       django不支持退出循环和continue操作

      a)增加列表是否为空的判断

{% for athlete in athlete_list %}
    <p>{{ athlete.name }}</p>
{% empty %}
    <p>There are no athletes. Only computer programmers.</p>
{% endfor %}

      b)反向循环

{% for athlete in athlete_list reversed %}
...
{% endfor %}

      c)记录循环次数

       forloop.counter:当前执行到第几次,以1开始

       forloop.counter0:当前执行的到的循环索引,以0开始

       forloop.revcounter:剩余的循环次数,以1结束

         forloop.revcounter0:剩余的循环索引,以0结束

       forloop.first:判断是否是第一次循环

       forloop.last:判断是否是最后一次循环

       eg:

{% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}

       可能生成的运行结果:

       

       forloop.parentloop: 在嵌套循环中使用,用于子循环引用上一级循环中的变量

        eg:

{% for country in countries %}
    <table>
    {% for city in country.city_list %}
        <tr>
        <td>Country #{{ forloop.parentloop.counter }}</td>
        <td>City #{{ forloop.counter }}</td>
        <td>{{ city }}</td>
        </tr>
    {% endfor %}
    </table>
{% endfor %}

    3)ifequal/ifnotequal标签

       用于判断变量是否相等,支持的类型(第二个参数):字符串、整数、小数

      ps:其他的列表类型,字典类型,布尔类型均不支持

      eg:

{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}

  4、模板中的注释

    单行注释:

{# This is a comment #}

    多行注释:

{% comment %}
This is a
multi-line comment.
{% endcomment %}

  5、过滤器

     常用过滤器:

def template_use(request):
    person_name='jimfeng'
    ship_date=datetime.datetime.now()
    item_list=[]
    item_list[0:0] = ['aaa']
    item_list[0:0] = ['bbb']
    item_list[0:0] = ['ccc']
    item_list.reverse();

    dic = {'person_name':person_name,'ship_date':ship_date,
           'item_list':item_list}

    return render_to_response('template_use.html', dic)
<html>
<head><title>Filter Test</title></head>

<body>

<h1>Filter Test</h1>

<p>length过滤器:<br>
   -----person_name字符串长度:{{ person_name|length }}<br>
   -----item_list长度:{{ item_list|length}}
</p>

{# 添加反斜杠到任何反斜杠、单引号或者双引号前面,常用语输出到js代码 #}
<p>转义字符过滤器:<br>
   -----特殊字符前加反斜杠,进行转义:{{ "A\B'CD"|addslashes }}<br>
</p>

<p>日期格式过滤器:<br>
   -----对日期进行指定格式的输出:{{ ship_date|date:"F j, Y" }}
</p>

<p>单词截取过滤器:<br>
   -----截取you are the right person to do these things前3个词:<br>
   -----{{ "you are the right person to do these things"|truncatewords:"3" }}
</p>

<p>列表第一个元素转换成大写(过滤器套接):<br>
   -----{{ item_list|first|upper }}
</p>

</body>
</html>

    运行结果:

    

三、使用模板

  1、从磁盘加载文件

    setting.py:指定模板文件路径

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, 'templates'),
)

    说明:如果TEMPLATE_DIRS中只包含了一个路径,则后面必须加上“,”,在

    单元素元组中使用逗号的目的,消除与圆括号表达式之间的歧义。

  2、views.py中使用模板

     1) views.py中使用loader从模板文件路径中获取指定的模板文件:

from django.template.loader import get_template

def template_use(request):
    person_name='jimfeng'
    ship_date=datetime.datetime.now()
    item_list=[]
    item_list[0:0] = ['aaa']
    item_list[0:0] = ['bbb']
    item_list[0:0] = ['ccc']
    item_list.reverse();

    t = get_template('template_use.html')
    html = t.render(template.Context({'person_name':person_name,'ship_date':ship_date,
           'item_list':item_list}))
    return HttpResponse(html)

    运行结果:

    

     2)更简洁的使用模板的方式

def template_use(request):
    person_name='jimfeng'
    ship_date=datetime.datetime.now()
    item_list=[]
    item_list[0:0] = ['aaa']
    item_list[0:0] = ['bbb']
    item_list[0:0] = ['ccc']
    item_list.reverse();

    return render_to_response('template_use.html', locals())

    说明:locals()方法,返回一个所有局部变量为元素的字典

    运行结果:

    

   3、关于模板子目录

      当模板根目录下有多个子目录时,可用过以下方式获取模板文件:

return render_to_response('dateapp/current_datetime.html', {'current_date': now})

   4、模板中include标签包含子模板

     views.py:

def template_use(request):
    person_name='jimfeng'
    ship_date=datetime.datetime.now()
    item_list=[]
    item_list[0:0] = ['aaa']
    item_list[0:0] = ['bbb']
    item_list[0:0] = ['ccc']
    item_list.reverse();

    return render_to_response('template_use.html', locals())

     inner.html:

<p>
    这是include标签包含进来的内部模板!!
</p>

     template_use.html:   

<html>
<head><title>Filter Test</title></head>

<body>

<h1>Filter Test</h1>

<p>length过滤器:<br>
   -----person_name字符串长度:{{ person_name|length }}<br>
   -----item_list长度:{{ item_list|length}}
</p>

{% include 'inner.html' %}
</body>
</html>

    运行结果:

    

  5、模板继承:比include更优雅的策略

     urls.py中新增的部分:

from django.conf.urls import patterns, url, include

urlpatterns = patterns('',
                       #...
                       (r'^template_inherit/$', 'django_web_app.views.template_inherit'),
)

     views.py中新增的部分:

def template_inherit(request):
    current_date=datetime.datetime.now()

    return render_to_response('child_template_current_time.html', locals())

    base_template.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>{% block title %}{% endblock %}</title>{# block:1 #}
</head>
<body>
    <h1>My helpful timestamp site</h1>
    {% block content %}{% endblock %}             {# block:2 #}
    {% block footer %}                            {# block:3 #}
    <hr>
    <p>Thanks for visiting my site.</p>
    {% endblock %}
</body>
</html>

    child_template_current_time.html:

{% extends "base_template.html" %}

{% block title %}当前时间{% endblock %}{# block:1 #}

{% block content %}
<p>填充content块:It is now {{ current_date }}.</p>{# block:2 #}
{% endblock %}

{% block footer %}
<p>footer块被覆盖: sssssssssssss</p>{# block:3 #}
{% endblock %}

    运行结果:

    

 

posted @ 2014-05-30 15:13  edisonfeng  阅读(848)  评论(0编辑  收藏  举报