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 %}
运行结果: