【8.0】Django框架之模板层
【一】模板语法的传值
{{}} : 变量相关
{%%} : 逻辑相关
【1】数据准备
路由
# 模板语法传值
url(r'^index/',views.index),
【2】基本数据类型
(1)视图
def index(request):
# 模板语法可以传递的后端Python数据类型
# 整型
a = 123
# 浮点型
b = 11.11
# 字符串
c = "这是一个示例"
# 列表
d = ["你好", "我好", "大家好"]
# 字典
e = {"username": "dream", "password": 1223, "host": "localhost"}
# 布尔
f = True
# 元祖
g = (11, 22, 33)
# 集合
h = {"阳阳", "可可"}
# 将所有数据打包发送给前端
return render(request, 'index.html', locals())
(2)前端
<p>整型 {{ a }}</p>
<p>浮点型 {{ b }}</p>
<p>字符串 {{ c }}</p>
<p>列表 {{ d }}</p>
<p>字典 {{ e }}</p>
<p>布尔 {{ f }}</p>
<p>元祖 {{ g }}</p>
<p>集合 {{ h }}</p>
(3)页面展示
整型 123
浮点型 11.11
字符串 这是一个示例
列表 ['你好', '我好', '大家好']
字典 {'username': 'dream', 'password': 1223, 'host': 'localhost'}
布尔 True
元祖 (11, 22, 33)
集合 {'可可', '阳阳'}
【3】函数
无返回值
from django.shortcuts import render, HttpResponse
# Create your views here.
from django.views import View
class MyLogin(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
return HttpResponse('POST OK')
def index(request):
# 模板语法可以传递的后端Python数据类型
# 整型
a = 123
# 浮点型
b = 11.11
# 字符串
c = "这是一个示例"
# 列表
d = ["你好", "我好", "大家好"]
# 字典
e = {"username": "dream", "password": 1223, "host": "localhost"}
# 布尔
f = True
# 元祖
g = (11, 22, 33)
# 集合
h = {"阳阳", "可可"}
# 函数
def func():
pass
# 将所有数据打包发送给前端
return render(request, 'index.html', locals())
函数 None
有返回值
from django.shortcuts import render, HttpResponse
# Create your views here.
from django.views import View
class MyLogin(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
return HttpResponse('POST OK')
def index(request):
# 模板语法可以传递的后端Python数据类型
# 整型
a = 123
# 浮点型
b = 11.11
# 字符串
c = "这是一个示例"
# 列表
d = ["你好", "我好", "大家好"]
# 字典
e = {"username": "dream", "password": 1223, "host": "localhost"}
# 布尔
f = True
# 元祖
g = (11, 22, 33)
# 集合
h = {"阳阳", "可可"}
# 函数
def func():
print("正在执行中....")
return '执行完成....'
# 将所有数据打包发送给前端
return render(request, 'index.html', locals())
- 终端打印
正在执行中....
- 页面展示
执行完成....
- 页面展示
整型 123
浮点型 11.11
字符串 这是一个示例
列表 ['你好', '我好', '大家好']
字典 {'username': 'dream', 'password': 1223, 'host': 'localhost'}
布尔 True
元祖 (11, 22, 33)
集合 {'阳阳', '可可'}
函数 执行完成....
总结
- 函数放到模版语法中会自动调用
- 但是模版语法不支持给函数添加其他的参数
【4】类与对象
类与对象
def index(request):
# 模板语法可以传递的后端Python数据类型
# 整型
a = 123
# 浮点型
b = 11.11
# 字符串
c = "这是一个示例"
# 列表
d = ["你好", "我好", "大家好"]
# 字典
e = {"username": "dream", "password": 1223, "host": "localhost"}
# 布尔
f = True
# 元祖
g = (11, 22, 33)
# 集合
h = {"阳阳", "可可"}
# 函数
def func():
print("正在执行中....")
return '执行完成....'
# 类
class MyClass(object):
# 普通方法
def get_self(self):
return 'my_self'
# 静态方法
@staticmethod
def get_func():
return 'my_func'
# 绑定给类的静态方法
@classmethod
def get_class(cls):
return 'my_class'
# 实例化对象
obj = MyClass()
# 将所有数据打包发送给前端
return render(request, 'index.html', locals())
整型 123
浮点型 11.11
字符串 这是一个示例
列表 ['你好', '我好', '大家好']
字典 {'username': 'dream', 'password': 1223, 'host': 'localhost'}
布尔 True
元祖 (11, 22, 33)
集合 {'可可', '阳阳'}
函数 执行完成....
自定义类 <app01.views.index.<locals>.MyClass object at 0x00000205E98FB048>
实例化对象 <app01.views.index.<locals>.MyClass object at 0x00000205E98D5358>
- 传类的时候也会自动调用类实例化出对象
- 对象就是原来的对象
对象调用方法
整型 123
浮点型 11.11
字符串 这是一个示例
列表 ['你好', '我好', '大家好']
字典 {'username': 'dream', 'password': 1223, 'host': 'localhost'}
布尔 True
元祖 (11, 22, 33)
集合 {'阳阳', '可可'}
函数 执行完成....
自定义类 <app01.views.index.<locals>.MyClass object at 0x000001FE31405438>
实例化对象 <app01.views.index.<locals>.MyClass object at 0x000001FE313DF2B0>
对象调用方法get_func my_func
对象调用方法get_class my_class
对象调用方法get_self my_self
- 可以调用对象的方法并拿到对应的返回值!
类对象内部的 __str__
方法
def index(request):
# 模板语法可以传递的后端Python数据类型
# 整型
a = 123
# 浮点型
b = 11.11
# 字符串
c = "这是一个示例"
# 列表
d = ["你好", "我好", "大家好"]
# 字典
e = {"username": "dream", "password": 1223, "host": "localhost"}
# 布尔
f = True
# 元祖
g = (11, 22, 33)
# 集合
h = {"阳阳", "可可"}
# 函数
def func():
print("正在执行中....")
return '执行完成....'
# 类
class MyClass(object):
# 普通方法
def get_self(self):
return 'my_self'
# 静态方法
@staticmethod
def get_func():
return 'my_func'
# 绑定给类的静态方法
@classmethod
def get_class(cls):
return 'my_class'
# 类被调用时一定会触发该方法
# 对象被展示到页面上时,就类似于执行了打印操作,也会触发__str__方法
def __str__(self):
return "我被调用啦!"
# 实例化对象
obj = MyClass()
# 将所有数据打包发送给前端
return render(request, 'index.html', locals())
整型 123
浮点型 11.11
字符串 这是一个示例
列表 ['你好', '我好', '大家好']
字典 {'username': 'dream', 'password': 1223, 'host': 'localhost'}
布尔 True
元祖 (11, 22, 33)
集合 {'阳阳', '可可'}
函数 执行完成....
自定义类 我被调用啦!
实例化对象 我被调用啦!
对象调用方法get_func my_func
对象调用方法get_class my_class
对象调用方法get_self my_self
-
类被调用时一定会触发该方法
-
对象被展示到页面上时,就类似于执行了打印操作,也会触发
__str__
方法
【小结】
- 模版语法会自动判断当前位置的变量名是否可以加括号调用
- 如果可以就会自执行
- 如果不能执行就会忽略
- 一般针对的是对象和类
【二】模版语法的取值
Django模版语法的取值,是固定的格式,只能采用“句点符”取值
- 可以通过
.键
取值 - 也可以通过
.索引
取值
<p>取值{{ e.username }}</p>
<p>取值{{ d.0 }}</p>
取值dream
取值你好
【三】过滤器
【1】过滤器
- 过滤器就类似于模版语法内置的内置方法
- Django内置有60多个过滤器
【2】语法
{{数据|过滤器:参数}}
【3】统计字符串长度
{{ c|length }}
6
- 源码
def length(value):
"""Returns the length of the value - useful for lists."""
try:
return len(value)
except (ValueError, TypeError):
return 0
【4】默认值
<p>默认值 {{ f|default:"这是默认值" }}</p>
-
类似于 get 方法
-
第一个参数如果是True,就会展示第一个值
-
如果第一个参数取不到,就会展示第二个值
-
-
源码
def default_if_none(value, arg):
"""If value is None, use given default."""
if value is None:
return arg
return value
【5】文件大小
<p>文件大小 {{ file|filesizeformat }}</p>
- 源码
def filesizeformat(bytes_):
"""
Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
102 bytes, etc.).
"""
try:
bytes_ = float(bytes_)
except (TypeError, ValueError, UnicodeDecodeError):
value = ungettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0}
return avoid_wrapping(value)
def filesize_number_format(value):
return formats.number_format(round(value, 1), 1)
KB = 1 << 10
MB = 1 << 20
GB = 1 << 30
TB = 1 << 40
PB = 1 << 50
negative = bytes_ < 0
if negative:
bytes_ = -bytes_ # Allow formatting of negative numbers.
if bytes_ < KB:
value = ungettext("%(size)d byte", "%(size)d bytes", bytes_) % {'size': bytes_}
elif bytes_ < MB:
value = ugettext("%s KB") % filesize_number_format(bytes_ / KB)
elif bytes_ < GB:
value = ugettext("%s MB") % filesize_number_format(bytes_ / MB)
elif bytes_ < TB:
value = ugettext("%s GB") % filesize_number_format(bytes_ / GB)
elif bytes_ < PB:
value = ugettext("%s TB") % filesize_number_format(bytes_ / TB)
else:
value = ugettext("%s PB") % filesize_number_format(bytes_ / PB)
if negative:
value = "-%s" % value
return avoid_wrapping(value)
【6】日期格式化
原始格式
current_time = datetime.datetime.now()
<p>日期格式化 {{ current_time }}</p>
日期格式化 July 12, 2023, 3:57 p.m.
格式化输出
<p>日期格式化 {{ current_time|date:'Y-m-d H:m:s' }}</p>
日期格式化 2023-07-12 15:07:45
【7】切片操作
支持步长切片
c = "这是一个示例"
<p>切片操作 {{ c|slice:'0:4:2' }}</p>
切片操作 这一
【8】切取摘要
- 可以指定切取长度
- 按照空格切分
字符
- 会将
.
算进切取个数
# 一串长文本只想截取某段数据
page = '# Nginx是什么? Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 ,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名 ...'
<p>切取字符 {{ page|truncatechars:10 }}</p>
切取字符 # Nginx...
单词
- 不会将
.
算进切取个数
# 切取单词
sentence = 'I just need someone who will never abandon me'
<p>切取单词 {{ sentence|truncatewords:9 }}</p>
切取单词 I just need someone who will never abandon me
【9】移除指定字符
sentence = 'I just need someone who will never abandon me'
<p>移除指定字符,例空格 {{ sentence|cut:" " }}</p>
移除指定字符,例空格 Ijustneedsomeonewhowillneverabandonme
【10】拼接字符
d = ["你好", "我好", "大家好"]
<p>拼接字符 {{ d|join:"$" }}</p>
拼接字符 你好$我好$大家好
【11】加法
a = 123
<p>拼接字符(加法) {{ a|add:10 }}</p>
拼接字符(加法) 133
- 源码
def add(value, arg):
"""Adds the arg to the value."""
try:
return int(value) + int(arg)
except (ValueError, TypeError):
try:
return value + arg
except Exception:
return ''
【12】取消转义
以后在写全栈项目时,前端代码不一定必须在前端页面书写
也可以选择先在后端写好,再传递给前端页面展示
前端转义
msg = '<h1>斋藤</h1>'
<p>转义字符(不转义) {{ msg }}</p>
<p>转义字符(转义) {{ msg|safe }}</p>
转义字符(不转义) <h1>斋藤</h1>
转义字符(转义)
斋藤(已变成h1标题格式)
后端转义
from django.utils.safestring import mark_safe
res = mark_safe('<h1>飞鸟</h1>')
<p>转义字符(转义) {{ res }}</p>
转义字符(转义)
飞鸟(已变成h1标题格式)
【四】标签
【1】forloop
d = ["你好", "我好", "大家好"]
{% for re in d %}
<p>{{ forloop }}</p>
{% endfor %}
标签
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 3, 'revcounter0': 2, 'first': True, 'last': False}
{'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}
{'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
-
first
- 标识 for 循环是否是第一次
-
last
- 标识 for 循环是否是以后一次
-
counter0
- 类似索引
-
counter
- 计数
-
取值
d = ["你好", "我好", "大家好"]
{% for re in d %}
<p>{{ re }}</p>
{% endfor %}
你好
我好
大家好
【2】if语句
f = True
{% if f %}
<p>你好</p>
{% else %}
<p>我好</p>
{% endif %}
你好
【3】混用 forloop + if
d = ["你好", "我好", "大家好"]
{% for re in d %}
{% if forloop.first %}
<p>第一次循环</p>
{% elif forloop.last %}
<p>最后一次循环</p>
{% else %}
<p>{{ re }}</p>
{% endif %}
{% empty %}
<p>for循环的对象是空,不支持for循环</p>
{% endfor %}
第一次循环
我好
最后一次循环
【五】自定义过滤器标签/inclusion_tag
-
三步走
-
要在应用下创建一个名字必须是templatetags文件夹
-
在该文件夹内创建 任意 名称的py文件
-
在该文件内必须写下面的话
from django import template register = template.Library()
-
【1】自定义过滤器
- 过滤器只能最多两个参数
(1)templatetags/my_tag.py
from django import template
register = template.Library()
@register.filter(name='dream')
def my_sum(x, y):
return x + y
(2)前端
import datetime
from django.shortcuts import render, HttpResponse
from django.utils.safestring import mark_safe
# Create your views here.
from django.views import View
class MyLogin(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
return HttpResponse('POST OK')
def index(request):
# 模板语法可以传递的后端Python数据类型
# 整型
a = 123
# 浮点型
b = 11.11
# 字符串
c = "这是一个示例"
# 列表
d = ["你好", "我好", "大家好"]
# 字典
e = {"username": "dream", "password": 1223, "host": "localhost"}
# 布尔
f = True
# 元祖
g = (11, 22, 33)
# 集合
h = {"阳阳", "可可"}
# 函数
def func():
print("正在执行中....")
return '执行完成....'
# 类
class MyClass(object):
# 普通方法
def get_self(self):
return 'my_self'
# 静态方法
@staticmethod
def get_func():
return 'my_func'
# 绑定给类的静态方法
@classmethod
def get_class(cls):
return 'my_class'
def __str__(self):
return "我被调用啦!"
# 实例化对象
obj = MyClass()
current_time = datetime.datetime.now()
# 一串长文本只想截取某段数据
page = '# Nginx是什么? Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器 ,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名 ...'
# 切取单词
sentence = 'I just need someone who will never abandon me'
# 转义
msg = '<h1>斋藤</h1>'
from django.utils.safestring import mark_safe
res = mark_safe('<h1>飞鸟</h1>')
# 将所有数据打包发送给前端
return render(request, 'index.html', locals())
<h1>自定义标签的使用</h1>
{% load my_tag %}
<p>{{ a|dream:666 }}</p>
789
【2】自定义标签
from django import template
register = template.Library()
@register.simple_tag(name='plus')
def index(a, b, c, d):
return f'{a}:{b}:{c}:{d}'
- 前端页面
<h1>自定义标签的使用</h1>
{% load my_tag %}
<p>{% plus 'dream' 521 369 789 %}</p>
dream:521:369:789
【3】自定义inclusion_tag
- 先定义一个方法
- 在页面上调用该方法,并且可以传值
- 该方法会生成一些数据然后传递给一个前端页面
- 再将渲染好的页面返回给前端
(1)templatetags/my_tag.py
# 自定义inclusion_tag
@register.inclusion_tag('left_menu.html')
def left(n):
data = ['第 {} 项'.format(n) for n in range(n)]
return locals() # 将data传递给 left_menu
(2)left_menu.html
<ul>
{% for datum in data %}
<li>{{ datum }}</li>
{% endfor %}
</ul>
(3)index.html
<h1>自定义标签的使用</h1>
{% load my_tag %}
{% left 10 %}
- 前端展示
第 0 项
第 1 项
第 2 项
第 3 项
第 4 项
第 5 项
第 6 项
第 7 项
第 8 项
第 9 项
(4)总结
- 当html页面的某一个地方的页面需要传参数才能动态的渲染出来,并且在多个页面上都需要使用到的局部,那么就考虑将该局部页面做成 inclusion_tag 形式
【六】模版的继承
- 某些页面的整体大差不差,但是某一些局部在做变化
本文来自博客园,作者:Chimengmeng,转载请注明原文链接:https://www.cnblogs.com/dream-ze/p/17559608.html