Django之模板层细说

django的模板层,基于我们前面学习的内容,也知道主要语法是{{变量相关}}{%逻辑相关%},那么具体还有哪些内容呢?且听我娓娓道来。

模板层(模板语法)

标签

过滤器

自定义标签,过滤器,inclusion_tag

模板的继承

模板的导入

1 标签

1.1 语法

首先两种特殊符号:

{{  }} 和   {%  %}

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

1.2 变量

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

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

  点(.)在模板语言中有特殊的含义。当模板系统遇到点("."),它将以如下的顺序进行查询:

  字典查询

  属性或方法查询

  数字索引查询

 

知道了基本语法和变量的一些规则,那么后端如何向前端传递数据呢?

后端朝前端页面传递数据的方式???

第一种

return render(request,'index.html',{'n':n})  # 字典的方式提交

第二种

return render(request,'index.html',locals())   # 注意,是将当前所在的名称空间名字中的名字全部传递到前端页面

具体示例如下

后端书写

注意:后端传函数名到前端,会自动加括号调用,但是不支持传参    没错,就是如此鸡肋,只要无参函数

   后端传一个类的对象到前端,相当于打印了这个对象

前端书写

那么如何获取到后端传过来的容器类型的元素里面的值?

  前端获取后端传过来的容器类型的内部元素,统一采用的是聚点符("."),如上图所示???  针对有序的容器类型采用索引取值,字典直接点key值。

注意:还是只能打印不需要传参的,传参的都不可以,了解即可

 

注释:模板语法的注释不会展示到前端页面  ,html的注释会展示到前端页面

 

1.3 逻辑判断相关

for循环

{% for foo in l %}
    <p>{{ foo }}</p>
    <p>{{ forloop }}</p>
{% endfor %}

 for循环可用的一些参数:

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

 

for...empty

当你的for循环对象为空的时候会自动走empty代码块儿的内容
后端:
l = None
前端:
{% for foo in l %}
    {% if forloop.first %}
    <p>这是我的第一次</p>
    {% elif forloop.last %}
    <p>这是最后一次了啊</p>
    {% else %}
    <p>嗨起来!!!</p>
    {% endif %}
    {% empty %}
    <p>你给我的容器类型是个空啊,没法for循环</p>
{% endfor %}

with

定义一个中间变量,多用于给一个复杂的变量起别名。

注意等号左右不要加空格。

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

 

{% with business.employees.count as total %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

 

 

if判断

{% if flag %}
    p>flag不为空</p>
    {% else %}
    <p>flag是空</p>
{% endif %}

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

{% if user_list %}
  用户人数:{{ user_list|length }}
{% elif black_list %}
  黑名单数:{{ black_list|length }}
{% else %}
  没有用户
{% endif %}

嵌套使用

{% for foo in l %}
    {% if forloop.first %}
    <p>这是我的第一次</p>
    {% elif forloop.last %}
    <p>这是最后一次了啊</p>
    {% else %}
    <p>嗨起来!!!</p>
    {% endif %}
{% endfor %}

注意事项

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

{% if a > b > c %}
...
{% endif %}

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

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

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

{{ data.items }}

默认会取d的items key的值。

csrf_token

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

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

2  过滤器

2.1 基本语法

统计长度 length

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

<p>{{ s|length }}</p>
<!--注意|左右不留空格-->
 
 

 

默认值 default

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

<p>{{ flag|default:'你这个东西是个空'}}</p>

 

数字格式化表示成文件大小 filesizeformat

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

<p>{{ file_size|filesizeformat }}</p>

格式化时间

格式化时间(不要加百分号)

<p>{{ ctime }}</p>
<p>{{ ctime|date:'Y-m-d' }}</p>

 可用的参数:

格式化字符描述示例输出
a'a.m.''p.m.'(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间)'a.m.'
A'AM''PM''AM'
b月,文字,3个字母,小写。'jan'
B未实现。 
cISO 8601格式。 (注意:与其他格式化程序不同,例如“Z”,“O”或“r”,如果值为naive datetime,则“c”格式化程序不会添加时区偏移量(请参阅datetime.tzinfo) 。2008-01-02T10:30:00.000123+02:002008-01-02T10:30:00.000123如果datetime是天真的
d月的日子,带前导零的2位数字。'01''31'
D一周中的文字,3个字母。“星期五”
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个字母。“扬”
n月无前导零。'1''12'
N美联社风格的月份缩写。 专有扩展。'Jan.''Feb.''March''May'
oISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。'1999年'
O与格林威治时间的差异在几小时内。'+0200'
P时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串“午夜”和“中午”。 专有扩展。'1 am''1:30 pm' / t3>,'midnight''noon''12:30 pm' / T10>
rRFC 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

字符串的切片操作

字符串的切片操作
<p>{{ res|slice:'0:8' }}</p>
指定长度进行切片
<p>{{ res|slice:'0:8:2' }}</p>

 

截取固定长度的字符串

截取固定的长度的字符串 三个点也算

<p>{{ s|truncatechars:10 }}</p>

 

按照空格截取文本内容

<p>{{ s|truncatewords:4 }}</p>

 

拼接(只能是同类型进行拼接)

<p>{{ 'hahah'|add:'heheheh' }}</p>    <!--可以-->
<p>{{ 'hahah'|add:123 }}</p>          <!--不可以-->
<p>{{ 123|add:'heheheh' }}</p>        <!--不可以-->

 cut

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

{{ value|cut:' ' }}

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

join

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

timesince

将日期格式设为自该日期起的时间(例如,“4天,6小时”)。

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

{{ blog_date|timesince:comment_date }}

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

timeuntil

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

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

{{ conference_date|timeuntil:from_date }}

取消转义(重点掌握****)

ht=<h1>我很安全的</h1>
sr=<script >我是安全的标签</script>

<p>{{ ht }}</p>     <!--前端显示结果是  "<h1>我很安全的</h1>"-->
<p>{{ sr }}</p>      <!--前端显示结果是  "<script>我是安全的标签</script>"-->
<p>{{ ht|safe }}</p>    <!--前端显示结果是h1样式的  我很安全的-->
<p>{{ sr|safe }}</p>   如果这个script里面来一个死循环,就会造成标签攻击,所以都不会直接存储为script

 图片如下???

 

 取消转义的两种方式

前端取消:

|safe

 

后端取消:

from django.utils.safestring import mark_safe
xxx = mark_safe('<h1>我是h1标签</h1>')

 

3 自定义过滤器 自定义标签  自定义inclusion_tag

首先,自定义过滤器标签都必须要做的三件事

1.在应用名下新建一个名为templatetags文件夹(必须叫这个名字)

2.在该新建的文件夹内新建一个任意名称的py文件

3.在该py文件中需要固定写下面两行代码

from django import template

register = template.Library()

 

自定义过滤器

@register.filter(name='XBB')    # 过滤器名字filter
def index(a,b):
    return a+b

 编写自定义的filter

from django import template
register = template.Library()


@register.filter(name="cut")
def cut(value, arg):
    return value.replace(arg, "")


@register.filter(name="addSB")
def add_sb(value):
    return "{} SB".format(value)

 

使用自定义的filter

 

{# 先导入我们自定义filter那个文件 #}
{% load app01_filters %}

{# 使用我们自定义的filter #}
{{ somevariable|cut:"0" }}
{{ d.name|addSB }}

自定义标签

@register.simple_tag
def plus(a,b,c):
    return a+b+c

自定义inclusion_tag

@register.inclusion_tag('login.html',name='login')   # 可以传参数,第一个是你要再那个页面使用,第二个是当前名字
def login(n):
    # l = []
    # for i in range(n):
    #     l.append('第%s项'%i)
    l = [ '第%s项'%i for i in range(n)]
    return {'l':l}

 

login.html

<ul>
    {% for foo in l %}
        <li>{{ foo }}</li>
    {% endfor %}
</ul>
# 调用
{% login 5 %}

 做好了自定义的标签,过滤器,那么如何使用呢?

首先你需要在要使用的html页面中加载你的py文件

{% load my_tag %}

 

然后再使用

{{ 666|XBB:8 }}
{% plus 1 2 3 %}
{% login 5 %}

 注意:???

 

4 模板的继承

4.1母版

首先需要在被继承的模板中划分多个区域
{% block 给区域起的名字 %}

{% endblock %}

通常情况下一个模板中应该至少有三块
{% block css %}
    页面css代码块
{% endblock %}

{% block js %}
    页面js代码块
{% endblock %}

{% block content %}
    页面主体内容
{% endblock %}

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Title</title>
  {% block page-css %}
  
  {% endblock %}
</head>
<body>

<h1>这是母板的标题</h1>

{% block page-main %}

{% endblock %}
<h1>母板底部内容</h1>
{% block page-js %}

{% endblock %}
</body>
</html>
母版

 

4.2继承母版

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

{% extends 'layouts.html' %}

 

4.3块(block)

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

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

{% block page-main %}
      <p>示儿</p>
    <p>死去元知万事空</p>
    <p>但悲不见九州同</p>
    <p>王师北定中原日</p>
    <p>家祭无忘告乃翁</p>
{% endblock %}

 

5 模块的导入

将一段html当作模块的方式导入到另一个html展示

{% include '想导入的html文件名' %}

 

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

{% include 'navbar.html' %}

 

6 静态文件的配置

{% static %}

<link rel='stylesheet' href="{% static 'css/mycss.css'%}">

 

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

 

 

引用JS文件时使用:

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

 

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

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

 

{% get_static_prefix %}

<link rel='stylesheet' href="{% get_static_prefix %}css/mycss.css">

 

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

 

或者

{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

 

simple tag

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

定义注册simple tag

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

 

使用自定义simple tag

{% load app01_demo %}

{# simple tag #}
{% plus "1" "2" "abc" %}

 

inclusion   tag

多用于返回html代码片段

示例:

templatetags/my_inclusion.py

from django import template

register = template.Library()


@register.inclusion_tag('result.html')
def show_results(n):
    n = 1 if n < 1 else int(n)
    data = ["第{}项".format(i) for i in range(1, n+1)]
    return {"data": data}

 

templates/snippets/result.html

<ul>
  {% for choice in data %}
    <li>{{ choice }}</li>
  {% endfor %}
</ul>

 

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>inclusion_tag test</title>
</head>
<body>

{% load inclusion_tag_test %}

{% show_results 10 %}
</body>
</html>

 

转载于:https://www.cnblogs.com/mcc61/p/11005351.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值