经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
Django之模板系统
来源:cnblogs  作者:爱吃玉米的小男孩  时间:2018/10/17 9:06:16  对本文有异议

首先看一段代码

  1. def current_datetime(request):
  2.     now = datetime.datetime.now()
  3.     html = "<html><body>It is now $s.</body></html>" $ nowreturn HttpResponse(html)

直接把HTML页面嵌套在视图函数里返回给浏览器并不是一个好主意;

原因:

1.对页面设计进行的任何改变都必须对python\代码进行相应的修改,牵一发而动全身;

2.Python代码编写和HTML设计是两项完全不同的工作,前端开发和后端开发无非并行;

基于这些原因,将HTML页面的设计和后端逻辑设计分离,会更简洁,容易维护开发我们的WEB应用.我们可以使用Django的模板系统(Template System)来实现这种模式.

模板是什么?

Django自带的模板语言 = HTML代码 + 逻辑控制代码,注意 模板 != HTML,模板 = HTML代码 + 逻辑控制代码(特殊标记);

模板作用?

在server端,把后端的变量嵌入到HTML中渲染后,返回给浏览器来达到前后端代码分离,页面动态显示的目的;

常用语法

只需要记住两种特殊符号:

{{  }}{%  %}

变量相关的用{{ }},逻辑相关的用{%  %}

变量

在Django的模板语言中按此语法使用:{{变量名}}.

当模板引擎遇到一个变量,他将计算这个变量,然后用结果替换它本身,变量的命名包括任何字母数字以及下划线("_")的组合.变量名称中不能有空格或者标点符号.

点(.)在模板语言中有特殊的含义,但模板系统遇到(.),它将以这样的顺序查询:

字典查询(Dictionary lookup)

属性或者方法查询((Attribute or\ method lookup)

数字索引查询(Numeric index lookup)

注意事项:

1.如果计算结果的值可调用的,它将被无参数的调用,调用的结果将成为模板的值.

2.如果使用的变量不存在,模板系统将插入string_if_invaild选项的值,它被默认设置为(空字符串).

几个例子:

view中的代码:

  1. def template_test(request):
  2.     l = [11, 22, 33]
  3.     d = {"name": "alex"}class Person(object):def __init__(self, name, age):
  4.             self.name = name
  5.             self.age = agedef dream(self):return "{} is dream...".format(self.name)
  6.  
  7.     Alex = Person(name="Alex", age=34)
  8.     Egon = Person(name="Egon", age=9000)
  9.     Eva_J = Person(name="Eva_J", age=18)
  10.  
  11.     person_list = [Alex, Egon, Eva_J]return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})

模板中支持的写法:

  1. {# l中的第一个参数 #}{{ l.0 }}
  2. {# 取字典中key的值 #}{{ d.name }}
  3. {# 取对象的name属性 #}{{ person_list.0.name }}
  4. {# .操作只能调用不带参数的方法 #}{{ person_list.0.dream }}

Fileters(过滤器)

在Django的模板语言中,通过使用过滤器来改变变量的显示.

过滤器的语法:{{value|filter_name:参数}}

使用管道符"|"来应用过滤器.

例如:{{name|lower]}会将name变量应用lower过滤器之后会再显示它的值.lower在这里的作用是将文本全部变成小写.

注意事项:

  1. 过滤器支持&ldquo;链式&rdquo;操作。即一个过滤器的输出作为另一个过滤器的输入。

  2. 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。

  3. 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}

  4. '|'左右没有空格没有空格没有空格

Django的模板语言中提供了大约六十个内置过滤器。

default

如果一个变量是false或者为空,使用给定的默认值.否则,使用变量的值.

  1. {{ value|default:"nothing"}}

如果value没有传值或者值为空的话就显示nothing

length

返回值的长度,作用于字符串和列表

{{value|length}}

返回value的长度,如value=['a','b','c','d']的话,就显示4.

filesizeformat

将值格式化为一个"人类可读的"文件尺寸(例如'13KB','4.1MB','102bytes',等等).例如:

  1. {{ value|filesizeformat }}

如果value是12345678,输出的结果将会是117.7MB.

slice

切片

  1. {{value|slice:"2:-1"}}

date

格式化

  1. {{ value|date:"Y-m-d H:i:s"}}

可用的参数:

 

格式化字符描述示例输出
a'a.m.''p.m.'(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间)'a.m.'
A'AM''PM''AM'
b月,文字,3个字母,小写。'jan'
B未实现。 
cISO 8601格式。 (注意:与其他格式化程序不同,例如&ldquo;Z&rdquo;,&ldquo;O&rdquo;或&ldquo;r&rdquo;,如果值为naive datetime,则&ldquo;c&rdquo;格式化程序不会添加时区偏移量(请参阅datetime.tzinfo) 。2008-01-02T10:30:00.000123+02:002008-01-02T10:30:00.000123如果datetime是天真的
d月的日子,带前导零的2位数字。'01''31'
D一周中的文字,3个字母。&ldquo;星期五&rdquo;
e时区名称 可能是任何格式,或者可能返回一个空字符串,具体取决于datetime。'''GMT''-500''US/Eastern'
E月份,特定地区的替代表示通常用于长日期表示。'listopada'(对于波兰语区域,而不是'Listopad'
f时间,在12小时的小时和分钟内,如果它们为零,则分钟停留。 专有扩展。'1''1:30'
F月,文,长。'一月'
g小时,12小时格式,无前导零。'1''12'
G小时,24小时格式,无前导零。'0''23'
h小时,12小时格式。'01''12'
H小时,24小时格式。'00''23'
i分钟。'00''59'
I夏令时间,无论是否生效。'1''0'
j没有前导零的月份的日子。'1''31'
l星期几,文字长。'星期五'
L布尔值是否是一个闰年。TrueFalse
m月,2位数字带前导零。'01''12'
M月,文字,3个字母。&ldquo;扬&rdquo;
n月无前导零。'1''12'
N美联社风格的月份缩写。 专有扩展。'Jan.''Feb.''March''May'
oISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。'1999年'
O与格林威治时间的差异在几小时内。'+0200'
P时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串&ldquo;午夜&rdquo;和&ldquo;中午&rdquo;。 专有扩展。'1 am''1:30 pm' / t3>,'midnight''noon''12:30 pm' / T10>
r RFC 5322格式化日期。'Thu, 21 Dec 2000 16:01:07 +0200'
s秒,带前导零的2位数字。'00''59'
S一个月的英文序数后缀,2个字符。'st''nd''rd''th'
t给定月份的天数。28 to 31
T本机的时区。'EST''MDT'
u微秒。000000 to 999999
U自Unix Epoch以来的二分之一(1970年1月1日00:00:00 UTC)。 
w星期几,数字无前导零。'0'(星期日)至'6'(星期六)
WISO-8601周数,周数从星期一开始。153
y年份,2位数字。'99'
Y年,4位数。'1999年'
z一年中的日子0365
Z时区偏移量,单位为秒。 UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。-4320043200

safe

Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器&ldquo;|safe&rdquo;的方式告诉Django这段代码是安全的不必转义。

比如:

value = "<a href='#'>点我</a>"

  1. {{value|safe}}

truncatechars

如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(&ldquo;...&rdquo;)结尾。

参数:截断的字符数

  1. {{ value|truncatechars:9}}

truncatewords

在一定数量的字后截断字符串。

  1. {{ value|truncatewords:9}}

cut

移除value中所有的与给出的变量相同的字符串

  1. {{ value|cut:' ' }}

如果value为'i love you',那么将输出'iloveyou'.

join

使用字符串连接列表,例如Python的str.join(list)

timesince

将日期格式设为自该日期起的时间(例如,&ldquo;4天,6小时&rdquo;)。

采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。 例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回&ldquo;8小时&rdquo;:

  1. {{ blog_date|timesince:comment_date }}

分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回&ldquo;0分钟&rdquo;。

timeuntil

似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。 例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回&ldquo;4周&rdquo;。

使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回&ldquo;1周&rdquo;:

  1. {{ conference_date|timeuntil:from_date }}

自定义filter

自定义过滤器只是带有一个或两个参数的Python函数:

  • 变量(输入)的值 - -不一定是一个字符串

  • 参数的值 - 这可以有一个默认值,或完全省略

例如,在过滤器{{var | foo:'bar'}}中,过滤器foo将传递变量var和参数&ldquo;bar&rdquo;

自定义filter代码文件摆放位置:

  1. app01/__init__.py
  2.     models.py
  3.     templatetags/  # 在app01下面新建一个package package__init__.py
  4.         app01_filters.py  # 建一个存放自定义filter的文件views.py

编写自定义filter

  1. from django import template
  2. register = template.Library()
  3.  
  4.  
  5. @register.filter(name="cut")def cut(value, arg):return value.replace(arg, "")
  6.  
  7.  
  8. @register.filter(name="addSB")def add_sb(value):return "{} SB".format(value)

使用自定义filter

  1. {# 先导入我们自定义filter那个文件 #}{% load app01_filters %}
  2.  
  3. {# 使用我们自定义的filter #}{{ somevariable|cut:"0" }}
  4. {{ d.name|addSB }}

tags

for

  1. <ul>{% for user in user_list %}<li>{{ user.name }}</li>{% endfor %}</ul>

for循环可用的一些参数:

VariableDescription
forloop.counter当前循环的索引值(从1开始)
forloop.counter0当前循环的索引值(从0开始)
forloop.revcounter当前循环的倒序索引值(从1开始)
forloop.revcounter0当前循环的倒序索引值(从0开始)
forloop.first当前循环是不是第一次循环(布尔值)
forloop.last当前循环是不是最后一次循环(布尔值)
forloop.parentloop本层循环的外层循环

for ... empty

  1. <ul>{% for user in user_list %}<li>{{ user.name }}</li>{% empty %}<li>空空如也</li>{% endfor %}</ul>

if,elif和else

  1. {% if user_list %}
  2.   用户人数:{{ user_list|length }}
  3. {% elif black_list %}
  4.   黑名单数:{{ black_list|length }}
  5. {% else %}
  6.   没有用户
  7. {% endif %}

当然也可以只要if和else

  1. {% if user_list|length > 5 %}
  2.   七座豪华SUV
  3. {% else %}
  4.     黄包车
  5. {% endif %}

if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

with

定义一个中间变量

  1. {% with total=business.employees.count %}
  2.     {{ total }} employee{{ total|pluralize }}
  3. {% endwith %}

csrf_token

这个标签用于跨站请求伪造保护。

在页面的form表单里面写上{% csrf_token %}

注释

  1. {# ... #}

注意事项

1. Django的模板语言不支持连续判断,即不支持以下写法:

  1. {% if a > b > c %}
  2. ...
  3. {% endif %}

2. Django的模板语言中属性的优先级大于方法

  1. def xx(request):
  2.     d = {"a": 1, "b": 2, "c": 3, "items": "100"}return render(request, "xx.html", {"data": d})

如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:

  1. {{ data.items }}

默认会取d的items key的值。

母版

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta http-equiv="x-ua-compatible" content="IE=edge">
  6.   <meta name="viewport" content="width=device-width, initial-scale=1">
  7.   <title>Title</title>
  8.   {% block page-css %}
  9.   
  10.   {% endblock %}</head>
  11. <body>
  12.  
  13. <h1>这是母板的标题</h1>{% block page-main %}
  14.  
  15. {% endblock %}<h1>母板底部内容</h1>{% block page-js %}
  16.  
  17. {% endblock %}</body>
  18. </html>

注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。

继承母版

在子页面中在页面最上方使用下面的语法来继承母板。

  1. {% extends 'layouts.html' %}

块(block)

通过在母板中使用{% block  xxx %}来定义"块"。

在子页面中通过定义母板中的block名来对应替换母板中相应的内容。

  1. {% block page-main %}  <p>世情薄</p>
  2.   <p>人情恶</p>
  3.   <p>雨送黄昏花易落</p>{% endblock %}

组件

可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。

  1. {% include 'navbar.html' %}

静态文件相关

  1. {% load static %}<img src="{% static "images/hi.jpg" %}" alt="Hi!" />

引用JS文件时使用:

  1. {% load static %}<script src="{% static "mytest.js" %}"></script>

某个文件多处被用到可以存为一个变量

  1. {% load static %}
  2. {% static "images/hi.jpg" as myphoto %}<img src="{{ myphoto }}"></img>

使用get_static_prefix

  1. {% load static %}<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

或者

  1. {% load static %}
  2. {% get_static_prefix as STATIC_PREFIX %}<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
  3. <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

自定义simpletag

和自定义filter类似,只不过接收更灵活的参数。

定义注册simple tag

  1. @register.simple_tag(name="plus")def plus(a, b, c):return "{} + {} + {}".format(a, b, c)

使用自定义simple tag

  1. {% load app01_demo %}
  2.  
  3. {# simple tag #}{% plus "1" "2" "abc" %}

inclusion_tag

多用于返回html代码片段

示例:

templatetags/my_inclusion.py

  1. from django import template
  2.  
  3. register = template.Library()
  4.  
  5.  
  6. @register.inclusion_tag('result.html')def show_results(n):
  7.     n = 1 if n < 1 else int(n)
  8.     data = ["第{}项".format(i) for i in range(1, n+1)]return {"data": data}

templates/snippets/result.html

  1. <ul>
  2.   {% for choice in data %}<li>{{ choice }}</li>
  3.   {% endfor %}</ul>

templates/index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta http-equiv="x-ua-compatible" content="IE=edge">
  6.   <meta name="viewport" content="width=device-width, initial-scale=1">
  7.   <title>inclusion_tag test</title>
  8. </head>
  9. <body>{% load inclusion_tag_test %}
  10.  
  11. {% show_results 10 %}</body>
  12. </html>

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号