Django 模板层

模板

一、模板语法之变量

  • {{ comment.create_time|date:"Y-m-d H:i:s" }}
  • {{ bio|truncatewords:"30" }}
  • {{ my_list|first|upper }}
  • {{ name|lower }}
  • {{ forloop.counter }}
  • {{ forloop.first }}
  • {{ forloop.last }}

在 Django 模板中遍历复杂数据结构的关键是句点字符, 语法: {{var_name}}

?
1
2
3
4
5
6
<h4>{{s}}< / h4>
<h4>列表:{{ l. 0 }}< / h4>
<h4>列表:{{ l. 2 }}< / h4>
<h4>字典:{{ dic.name }}< / h4>
<h4>日期:{{ date.year }}< / h4>
<h4>类对象列表:{{ person_list. 0.name }}< / h4>

二、模板之过滤器

语法:{{obj|filter__name:param}}

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
default:如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
{{ value|default: "nothing" }}
  
length:返回值的长度。它对字符串和列表都起作用。例如:
{{ value|length }} 如果 value 是 [ 'a' , 'b' , 'c' , 'd' ],那么输出是 4
  
filesizeformat:将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB' , '4.1 MB' , '102 bytes' , 等等)。例如:
{{ value|filesizeformat }} 如果 value 是 123456789 ,输出将会是 117.7 MB。  
  
date:如果 value = datetime.datetime.now()
{{ value|date: "Y-m-d" }}  
  
slice :如果 value = "hello world"
{{ value| slice : "2:-1" }}
  
truncatechars:
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:要截断的字符数
{{ value|truncatechars: 9 }}
  
safe:Django的模板中会对HTML标签和JS等语法标签进行自动转义,这样是为了安全。如果不希望HTML元素被转义,可以这样:
value = "<a href=" ">点击</a>"
{{ value|safe}}

这里简单介绍一些常用的模板的过滤器,更多详见

三、模板之标签

标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。

1、for标签

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"""
遍历每一个元素:
{% for person in person_list %}
     <p>{{ person.name }}</p>
{% endfor %}
可以利用{% for obj in list reversed %}反向完成循环。
 
遍历一个字典:
{% for key,val in dic.items %}
     <p>{{ forloop.counter }} {{ key }}:{{ val }}</p>
{% endfor %}
注:循环序号可以通过{{ forloop }}显示  
 
forloop.counter            The current iteration of the loop (1-indexed)
forloop.counter0           The current iteration of the loop (0-indexed)
forloop.revcounter         The number of iterations from the end of the loop (1-indexed)
forloop.revcounter0        The number of iterations from the end of the loop (0-indexed)
forloop.first              True if this is the first time through the loop
forloop.last               True if this is the last time through the loop
"""

2、for ... empty

?
1
2
3
4
5
6
<! - - for 标签带有一个可选的{ % empty % } 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。 - - >
{ % for person in person_list % }
     <p>{{ forloop.counter0 }} {{ person.name }} , {{ person.age }}< / p>
{ % empty % }
     <p>列表为空< / p>
{ % endfor % }

3、if 标签

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<! - - 注意: filter 可以用在 if 等语句后,simple_tag不可以 - - >
{ % if i|multi_fliter: 10 > 100 % }
     <p> 100 < / p>
{ % else % }
     <p>{{ i }}< / p>
{ % endif % }
 
<! - - 多分支 - - >
{ % if num > 100 or num < 0 % }
     <p>无效< / p>
{ % elif num > 80 and num < 100 % }
     <p>优秀< / p>
{ % else % }
     <p>凑活吧< / p>
{ % endif % }

4、with

?
1
2
3
4
5
<! - - 使用一个简单地名字缓存一个复杂的变量 - - >
{ % with person_list. 1.name as n % }
     {{ n }}
     {{ n }}
{ % endwith % }

5、csrf_token

?
1
2
3
4
5
<form action = " " method=" post">
     { % csrf_token % }  <! - - 这个标签用于跨站请求伪造保护 - - >
     < input type = "text" name = "user" >
     < input type = "submit" >
< / form>

四、自定义标签和过滤器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""
1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
2、在app中创建templatetags包(包名只能是templatetags)
3、创建任意 .py 文件,如:my_tags.py
4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
5、使用simple_tag和filter(如何调用)
注意:filter可以用在if等语句后,simple_tag不可以
"""
 
#settings.py
INSTALLED_APPS = [
     'django.contrib.admin' ,
     'django.contrib.auth' ,
     'django.contrib.contenttypes' ,
     'django.contrib.sessions' ,
     'django.contrib.messages' ,
     'django.contrib.staticfiles' ,
     "app01" , #配置当前app
]
 
# app01.templatetags.my_tags.py
from django import template
from django.utils.safestring import mark_safe
 
register = template.Library()  # register的名字是固定的,不可改变
 
@register . filter       #自定义过滤器最多2个参数
def multi_fliter(v1, v2):
     return v1 * v2
 
@register .simple_tag   #自定义标签,没有参数个数限制
def multi_tag(v1, v2, v3):
     return v1 * v2 * v3
 
@register .simple_tag
def my_input( id , arg):
     result = "<input type='text' id='%s' class='%s' />" % ( id , arg,)
     return mark_safe(result)
 
#模板中:
"""
{% load my_tags %}  <!--注意:这块更改过要重启项目-->
# num = 8
<p>{{ num|multi_fliter:20 }}</p>
<p>{% multi_tag 7 9 6 %}</p>
 
<!--注意:filter可以用在if等语句后,simple_tag不可以-->
{% if num|multi_fliter:10 > 100 %}
     <p>100</p>
{% else %}
     <p>{{ num }}</p>
{% endif %}
"""

五、模板之inclusion_tag

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# app01.templatetags.my_tags.py
 
from django import template
from django.db.models import Count
from app01 import models
register = template.Library()
 
 
@register .simple_tag
def multi_tag(x,y):
     return x * y
 
 
@register .inclusion_tag( "classification.html" )
def get_classification_style(username):
 
     user = models.UserInfo.objects. filter (username = username).first()
     blog = user.blog
 
     cate_list = models.Category.objects. filter (blog = blog).values( "pk" ).annotate(c = Count( "article__title" )).values_list( "title" , "c" )
 
     tag_list = models.Tag.objects. filter (blog = blog).values( "pk" ).annotate(c = Count( "article" )).values_list( "title" , "c" )
 
     date_list = models.Article.objects. filter (user = user).extra(select = { "y_m_date" : "date_format(create_time,'%%Y/%%m')" }).values( "y_m_date" ).annotate(c = Count( "nid" )).values_list( "y_m_date" , "c" )
 
 
     return { "blog" :blog, "cate_list" :cate_list, "date_list" :date_list, "tag_list" :tag_list}
 
 
#模板中:使用
"""
  <div class="col-md-3 menu">
              {% load my_tags %}
              {% get_classification_style username %}
  </div>
"""
 
 
#templates.classification.html
"""
  <div>
     <div class="panel panel-warning">
                 <div class="panel-heading">我的标签</div>
                 <div class="panel-body">
                     {% for tag in tag_list %}
                         <p><a href="/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p>
                     {% endfor %}
 
                 </div>
             </div>
 
     <div class="panel panel-danger">
         <div class="panel-heading">随笔分类</div>
         <div class="panel-body">
             {% for cate in cate_list %}
                 <p><a href="/{{ username }}/category/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p>
             {% endfor %}
         </div>
     </div>
 
     <div class="panel panel-success">
         <div class="panel-heading">随笔归档</div>
         <div class="panel-body">
             {% for date in date_list %}
                 <p><a href="/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p>
             {% endfor %}
         </div>
     </div>
  </div>
"""

六、模板继承 (extend)

  • 不能在一个模版中定义多个相同名字的 block 标签。
  • 为了更好的可读性,你也可以给你的 {% endblock %} 标签一个 名字 。例如:{% block content %}...{% endblock content %}
  • 子模版不必定义全部父模版中的blocks
  • {% extends 'base.html' %}

1、制作模板

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<! - - 模版 base.html - - >
<!DOCTYPE html>
<html lang = "en" >
<head>
     <meta charset = "UTF-8" >
     { % block title % }
     <title>base< / title>
     { % endblock % }
 
     { % block css % } { % endblock % }
< / head>
<body>
 
<div class = "header" >< / div>
<div class = "container" >
     <div class = "row" >
         <div class = "col-md-3" >
             { % include 'left1.html' % }  <! - - 引入小组件 - - >
             { % include 'ad.html' % }  <! - - 引入小组件 - - >
         < / div>
         <div class = "col-md-9" >
              
             { % block con % }
               <h4>content< / h4>
             { % endblock content % }  <! - - 更好的可读性 - - >
             
         < / div>
     < / div>
< / div>
 
{ % block js % }{ % endblock % }
< / body>
< / html>

2、继承模板

?
1
2
3
4
5
6
7
8
9
10
11
12
{ % extends 'base.html' % } <! - - 它必须是模版中的第一个标签。 - - >
 
{ % block title % }
<title>orders< / title>
{ % endblock % }
 
{ % block con % }
{{ block. super }}  <! - - 获取模板中con的内容 - - >
<h4>订单< / h4>
{ % endblock con % }
 
<! - - order.html - - >

七、模板多对多调用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Student(models.Model):
     name = models.CharField(max_length = 128 )
  
class Course(models.Model):
     name = models.CharField(max_length = 128 )
     students = models.ManyToManyField( 'Student' )
  
正向查询:
从course往student查
def test(request):
     course = models.Course.objects.get(pk = 1 )
     return render(request, 'course.html' , locals ())
  
获取了 id 1 的course对象,并将它传递给course.html模版,模版代码如下:
{ % for student in course.students. all % }
<p>{{ student.name }}< / p>
{ % endfor % }
首先通过course.students. all ,查寻到course对象关联的students对象集,然后用 for 标签循环它,获取每个student对象,再用student模型的定义,访问其各个字段的属性。
  
  
反向查询:
从student往course查,假设有如下的视图:
def test2(request):
     student = models.Student.objects.get(pk = 1 )
     return render(request, 'student.html' , locals ())
  
获取了 id 1 的student对象,并将它传递给student.html模版,模版代码如下:
{ % for course in  student.course_set. all % }
{{ course.name }}
{ % endfor % }
通过student.course_set. all ,反向获取到student实例对应的所有course对象,然后再 for 标签循环每个course,调用course的各种字段属性。
  
####
对于外键ForeignKey,其用法基本类似。只不过正向是obj.fk,且只有 1 个对像,不是集合。反向则是obj.fk_set,类似多对多。

八、内置模板标签

标签说明
autoescape自动转义开关
block块引用
comment注释
csrf_tokenCSRF令牌
cycle循环对象的值
debug调试模式
extends继承模版
filter过滤功能
firstof输出第一个不为False的参数
for循环对象
for … empty带empty说明的循环
if条件判断
ifequal如果等于
ifnotequal如果不等于
ifchanged如果有变化,则..
include导入子模版的内容
load加载标签和过滤器
lorem生成无用的废话
now当前时间
regroup根据对象重组集合
resetcycle重置循环
spaceless去除空白
templatetag转义模版标签符号
url获取url字符串
verbatim禁用模版引擎
widthratio宽度比例
with上下文变量管理器

九、内置过滤器总览

为模版过滤器提供参数的方式是:过滤器后加个冒号,再紧跟参数,中间不能有空格! 目前只能为过滤器最多提供一个参数!

过滤器说明
add加法
addslashes添加斜杠
capfirst首字母大写
center文本居中
cut切除字符
date日期格式化
default设置默认值
default_if_none为None设置默认值
dictsort字典排序
dictsortreversed字典反向排序
divisibleby整除判断
escape转义
escapejs转义js代码
filesizeformat文件尺寸人性化显示
first第一个元素
floatformat浮点数格式化
force_escape强制立刻转义
get_digit获取数字
iriencode转换IRI
join字符列表链接
last最后一个
length长度
length_is长度等于
linebreaks行转换
linebreaksbr行转换
linenumbers行号
ljust左对齐
lower小写
make_list分割成字符列表
phone2numeric电话号码
pluralize复数形式
pprint调试
random随机获取
rjust右对齐
safe安全确认
safeseq列表安全确认
slice切片
slugify转换成ASCII
stringformat字符串格式化
striptags去除HTML中的标签
time时间格式化
timesince从何时开始
timeuntil到何时多久
title所有单词首字母大写
truncatechars截断字符
truncatechars_html截断字符
truncatewords截断单词
truncatewords_html截断单词
unordered_list无序列表
upper大写
urlencode转义url
urlizeurl转成可点击的链接
urlizetruncurlize的截断方式
wordcount单词计数
wordwrap单词包裹
yesno将True,False和None,映射成字符串‘yes’,‘no’,‘maybe’

转载于:https://www.cnblogs.com/bubu99/p/10447953.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值