55.模板层
模板层
【一】模板语法的传值
{{ }}:变量渲染
{% %}:逻辑渲染语法
1)变量
- 变量渲染:直接渲染后端传入的变量即可
- 变量取值:从字典或列表中取值
2)基本数据类型
# views.py
def homepage(request):
num_eg = 123
fool_eg = 1.23
str_eg = '字符串'
list_eg = ['列表1', '列表2']
dict_eg = {'dict': '字典', 'num': 11}
bool_eg = True
tuple_eg = ('元组', 22)
set_eg = {'集合', 33, 33}
return render(request, 'homepage.html', locals())
# html
<p>
整数:{{ num_eg }}<br>
浮点数: {{ fool_eg }}<br>
字符串: {{ str_eg }}<br>
列表: {{ list_eg }}<br>
字典: {{ dict_eg }},取值:{{ dict_eg.num }}<br>
布尔: {{ bool_eg }}<br>
元组: {{ tuple_eg }}<br>
集合: {{ set_eg }}(会自动去重)
</p>
3)函数
# views.py
def homepage(request):
# 无返回值函数
def eg_1():
print('无返回值函数')
# 有返回值函数
def eg_2():
return '有返回值函数'
return render(request, 'homepage.html', locals())
# html
<h1>函数</h1>
<p>无返回值函数:{{ eg_1 }}</p>
<p>有返回值函数:{{ eg_2 }}</p>
- 无返回值函数:None
- 有返回值函数:有返回值函数
- 无法渲染有参函数,因为无法传递参数给后端
4)类与对象
class User(object):
print('user_eg类被执行')
def __init__(self, name):
self.name = name
# 绑定给对象
def eg_obj(self):
print('eg_obj被执行')
return 'eg_obj的返回值'
# 绑定给类
@classmethod
def eg_cls(cls):
print('eg_cls被执行')
return 'eg_cls的返回值'
# 静态方法
@staticmethod
def eg_any():
print('eg_any被执行')
return 'eg_any的返回值'
# 定制打印对象的时候触发的内容
def __str__(self):
return f'my name is {self.name}'
# 初始化类的得到对象
obj = User(name='ST1')
# html
<h1>类与对象</h1>
<p>绑定给对象:{{ obj.eg_obj }}</p>
<p>绑定给类:{{ obj.eg_cls }}</p>
<p>静态方法:{{ obj.eg_any }}</p>
<p>类产生的对象:{{ obj }}</p>
<p>对象调用自己的属性:{{ obj.name }}</p>
-
对象调用对象的绑定方法
- 语法:{{ obj.eg_obj }}
- 返回当前函数的返回值
-
类调用对象的绑定方法
- 语法:{{ User.eg_any }}
- 没有结果
-
类产生的对象
- my name is ST1
- 当你对类内部的
__str__
重写以后 再打印对象 就是你定制后的结果
-
对象调用自己的属性
- ST1
【二】过滤器
1)语法
{{数据|过滤器名字:过滤器的语法}}
2)计算长度(length)
# views
name = "ST1"
num_list = [1, 2, 3,4]
# html
<p>{{ name|length }}</p>
<p>{{ num_list|length }}</p>
#
# 输出
3
3
3)默认值(default)
- 当前面的value 为真的时候会渲染自己的值
- 如果为假则渲染默认值
# views
acquiesce_eg_1 = True
acquiesce_eg_2 = False
# html
<p>{{ acquiesce_eg_1|default:'默认值' }}</p>
<p>{{ acquiesce_eg_2|default:'默认值' }}</p>
# 输出
True
默认值
4)文件大小(filesizeformat)
{{ value|filesizeformat }}
5)日期格式化(date)
{{ 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 | 未实现。 | |
c | ISO 8601格式。 (注意:与其他格式化程序不同,例如“Z”,“O”或“r”,如果值为naive datetime,则“c”格式化程序不会添加时区偏移量。 | 2008-01-02T10:30:00.000123+02:00或2008-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 | 布尔值是否是一个闰年。 | True或False |
m | 月,2位数字带前导零。 | '01'到'12' |
M | 月,文字,3个字母。 | “扬” |
n | 月无前导零。 | '1'到'12' |
N | 美联社风格的月份缩写。 专有扩展。 | 'Jan.','Feb.','March','May' |
o | ISO-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> |
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'(星期六) |
W | ISO-8601周数,周数从星期一开始。 | 1,53 |
y | 年份,2位数字。 | '99' |
Y | 年,4位数。 | '1999年' |
z | 一年中的日子 | 0到365 |
Z | 时区偏移量,单位为秒。 UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。 | -43200到43200 |
6)切片操作(slice)
{{value|slice:'起始索引:终止索引:步长' }}
示例
# views
data = 'abcdefg'
# html
<p>切片操作 {{ data|slice:'0:4:2' }}</p>
# 输出
ace
7)切取摘要(truncatechars)
{{ page|truncatechars:指定个数 }}
示例
# views
page = 'abcdefghijklmnopqrstuvwxyz'
# html
<p>{{ page|truncatechars:5 }}</p>
# 输出
abcd…
8)移除指定字符(cut)
{{ sentence|cut:" " }} ---> 移除掉字符串中间的特殊字符
9)拼接字符(join)
# views
d = ["你好", "我好", "大家好"]
# html
<p>{{ d|join:"$" }}</p>
# 输出
你好$我好$大家好
10)加法(add)
# views
a = 1
# html
<p>{{ a|add:10 }}</p>
# 输出
11
11)取消转义(mark_safe和safe)
# views
html_str = '<h1>取消转义</h1>'
- 前端转义
# html
<p>不转义:{{ html_str }}</p>
<p>转义:{{ html_str|safe }}</p>
# 输出
不转义:<h1>取消转义</h1>
转义:取消转义(为页面正常一级标题内容)
- 后端转义
html_str = '<h1>取消转义</h1>'
from django.utils.safestring import mark_safe
html_str = mark_safe(html_str)
12)timesince
- 将日期格式设为自该日期起的时间
{{ blog_date|timesince:comment_date }}
13)timeuntil
- 似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间
- 使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量
{{ conference_date|timeuntil:from_date }}
【三】标签语法
1)for循环
1.普通for循环
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
2.部分参数
Variable | Description |
---|---|
forloop.counter | 当前循环的索引值(从1开始) |
forloop.counter0 | 当前循环的索引值(从0开始) |
forloop.revcounter | 当前循环的倒序索引值(从1开始) |
forloop.revcounter0 | 当前循环的倒序索引值(从0开始) |
forloop.first | 当前循环是不是第一次循环(布尔值),是返回True |
forloop.last | 当前循环是不是最后一次循环(布尔值),是返回True |
forloop.parentloop | 本层循环的外层循环 |
3.for...empty
- 有值正常执行,没值执行empty
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% empty %}
<li>空空如也</li>
{% endfor %}
</ul>
2)if判断
1.if ~ elif ~ else
{% if user_list %}
用户人数:{{ user_list|length }}
{% elif black_list %}
黑名单数:{{ black_list|length }}
{% else %}
没有用户
{% endif %}
- if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断
2.with
- 定义一个中间量,多用于给一个复杂的变量起别名
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
【四】自定义过滤器标签(inclusion_tag)
1)使用步骤
-
现在应用下创建一个templatetags文件夹
-
在该文件夹内创建一个py文件
-
在该文件引入模块
from django import template register = template.Library()
2)自定义过滤器
# templatetags\index_tag.py
# 引入模块
from django import template
# 创建一个注册对象
register = template.Library()
# 创建函数,加指定装饰器
@register.inclusion_tag('index.html')
def eg_tag(n):
data = ['第{}项'.format(n) for n in range(n)]
return locals()
# 创建注册的页面(index.html)
<h1>这是index_eg页面</h1>
<p>使用注册的标签</p>
<ul>
{% for datum in data %}
<li>{{ datum }}</li>
{% endfor %}
</ul>
# 场景使用以注册给页面样式(homepage.html)
{% load index_tag %}
{% eg_tag 10 %}
【五】模板的继承
- 做一个模板页面,在页面的某块做一个声明
- 在另一个页面上可直接将这一块内容进行替换
# 【一】创建模板页面
# 正常书写文件样式
# 在页面上进行规划,将可替换部分包在指定内容里
{% block main_content %}
主体内容,可替换部分
{% endblock %}
# 【二】找到需要渲染模板的页面
# html文件什么都不需要写,直接写如下内容
{% extends '模板文件名' %}
{% block main_content %}
<div>
<h1>自主写入的内容</h1>
</div>
{% endblock %}
【六】静态文件加载
1)
- 加载Django的静态文件
{% load static %}
<img src="{% static "文件名" %}" alt="Hi!" />
- 引用JS文件时使用:
{% load static %}
<script src="{% static "文件名" %}"></script>
- 某个文件多处被用到可以存为一个变量
{% load static %}
{% static "文件名" as myphoto %}
<img src="{{ myphoto }}"></img>
2)
- 相当于获取到了 static 文件夹的文件夹绝对路径,从绝对路径再往下找静态文件
{% load static %}
<img src="{% get_static_prefix %}文件名" alt="Hi!" />
- 或者
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
<img src="{{ STATIC_PREFIX }}文件名" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}文件名" alt="Hello!" />