模版
1.寻找html模版
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
# 'django.contrib.auth.context_processors.auth',
# 'django.contrib.messages.context_processors.messages',
],
},
},
]
优先去项目根目录 > 每个已注册的app的templates目录找
2. 模版层渲染前端步骤
# 第一步 在视图函数中 在render对象中添加一个参数 locals()
# locals() ---> 获取到当前的名称空间
# 传给了 render 函数中的第三个参数 context 参数 上下文对象
def register(request):
# 【一】字符串类型的数据
name = "serein"
return render(request, 'register.html', locals())
3. 前端渲染的八大基本数据类型
def index(request):
# 字符串类型
n1 = "hello world"
# 数字类型
# 整型
age = 19
# 小数类型
money = 100.98
# 列表
num = [1, 2, 3, 4]
# 字典类型
user_data = {"username": "serein", "password": "123", "age": 22, "hobby": ["music", "sport", "walk"],
"addr": {"country": "China", "location": "Shanghai"}}
# 布尔类型
is_right = 2>3
# 元组类型
num_tuple = (1, 2, 3, 4, 5)
# 【七】集合类型
num_set = {1, 2, 3, 4, 5, 5, 5}
return render(request, 'app01/index.html', locals())
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#字符串#}
<h1>index首页{{ n1 }}</h1>
{#整数#}
<p>{{ age }}</p>
{#浮点数字#}
<p>{{ money }}</p>
<ul>
{#列表#}
{% for i in num %}
<li>{{ i }}</li>
{% endfor %}
</ul>
{#字典类型值,直接.获取#}
<p>{{ user_data.addr.location }}</p>
{#布尔类型#}
<p>{{ is_right }}</p>
{#元祖#}
<p>{{ num_tuple }}</p>
{#集合#}
<p>{{ num_set}}</p>
</body>
</html>
4.前端渲染函数和类
4.1 渲染函数
- 渲染函数
- 函数无返回值渲染结果是none
- 函数有汗绘制渲染出来的是指定返回值
def function(request):
# 无返回值
def demo1():
content = f"这是demo1函数"
print(content)
# 有返回值
def demo2():
content = f"这是demo2函数"
return content
return render(request, 'app01/demo.html', locals())
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>{{ demo1 }}</p>
<p>{{ demo2 }}</p>
</body>
</html>
4.2 渲染类
- 渲染对象,就是相当于触发了 Student 类的__str__ 方法
def cls_function(request):
class Student:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
# 绑定给对象的方法
def read(self):
print(f"{self.name} 正在看书")
return f"这是绑定给对象的方法"
# 绑定给类的方法
@classmethod
def wirte(cls):
return f"这是绑定给类的方法"
@staticmethod
def sleep():
return f"当前非绑定方法"
def __str__(self):
return f'这是 Student 类'
student = Student('serein', 18, 'male')
return render(request, 'app01/student.html', locals())
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#渲染对象,其实就是相当于触发了 Student 类的__str__ 方法#}
{{ student }}
{#渲染对象属性#}
{{ student.name }}
{#渲染对象的绑定方法和非绑定方法#}
{#绑定给对象的方法#}
{{ student.read }}
{#绑定给类的方法#}
{{ student.wirte }}
{#非绑定方法#}
{{ student.sleep }}
</body>
</html>
5.过滤器
5.1 过滤器简介
在Django的模板语言中,通过使用 过滤器 来改变变量的显示
5.2 语法
{{数据|过滤器:参数}}
注意事项:
- 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
- 过滤器可以接受参数,例如:
{{ sss|truncatewords:30 }}
,这将显示sss的前30个词。 - 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:
{{ list|join:', ' }}
|
左右没有空格!没有空格!没有空格!
5.3 常用过滤器
def demo3(request):
name = 'serein'
name1 = 'SEREIN'
age = ''
current_time = datetime.datetime.now()
list1 = [1, 2, 3, 4, 5]
html_content = "<p>蒹葭苍苍,白露为霜,所谓伊人,在水一方。</p>"
# 第一种方法用mark_safe
html_content = mark_safe(html_content)
return render(request, 'app01/demo3.html', locals())
{% load jp %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#计算变量长度#}
{{ name|length }}
{#变大写#}
<p>{{ name|upper }}</p>
{#变小写#}
<p>{{ name1|lower }}</p>
{#指定默认值#}
<p>{{ age|default:18 }}</p>
{#格式化日期对象#}
<p>{{ current_time|date:"Y-m-d H:i:s" }}</p>
{#切片,顾头不顾尾#}
<p>{{ list1|slice:"0:2" }}</p>
{#切取摘要#}
<div>{{ list1|truncatechars:9 }}</div>
{#移除指定字符#}
<div>{{ name }}</div>
<div>{{ name|cut:"r" }}</div>
{#拼接,可以拼接的前提是后端的数据可以迭代#}
<div>{{ list1 }}</div>
<div>{{ list1|join:"|" }}</div>
{#取消转义#}
{#<div>{{ html_content }}</div>#}
{#第二种方法#}
<div>{{ html_content|safe }}</div>
<h2>{{ name|myfunc }}</h2>
</body>
</html>
5.4 自定义过滤器方法模版
- 使用template模块
- 在app下创建temolatetags文件夹
- 创建所需要自定义的方法的py文件
- 在前端顶部导入
from django import template
register = template.Library()
# filter存在参数个数限制
@register.filter
def myfunc(value):
return value.upper()
# simple_tag 不存在参数个数限制,返回文本
@register.simple_tag()
def mytag1():
return "哈哈哈"
@register.simple_tag()
def mytag2(a1, a2):
return a1 + a2
# inclusion_tag 不存在参数个数限制,返回html片段
@register.inclusion_tag("app01/xxxxx.html")
def xxx():
return {"name": "serein", "age": 73}
{% load jp %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>{{ name|myfunc }}</h2>
<p>{% mytag1 %}</p>
<p>{% mytag2 'xxx' 'aaa' %}</p>
# 返回的是inclusion_tag("app01/xxxxx.html")里的内容
<p>{% xxx %}</p>
</body>
</html>
6. 标签(tags)
6.1 for循环
6.1.1普通for循环
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
6.1.2 for循环可用的一些参数:
Variable | Description |
---|---|
forloop.counter |
当前循环的索引值(从1开始) |
forloop.counter0 |
当前循环的索引值(从0开始) |
forloop.revcounter |
当前循环的倒序索引值(从1开始) |
forloop.revcounter0 |
当前循环的倒序索引值(从0开始) |
forloop.first |
当前循环是不是第一次循环(布尔值) |
forloop.last |
当前循环是不是最后一次循环(布尔值) |
forloop.parentloop |
本层循环的外层循环 |
6.1.3 for ... empty
这是 Django 模板中的一段代码,用于在模板中遍历一个用户列表并显示用户的姓名。这段代码使用了模板中的 {% for %}
模板标签和 {% empty %}
来处理列表为空的情况
具体而言,这段代码做了以下事情:
{% for user in user_list %}
: 遍历user_list
列表中的每个用户对象。<li>{{ user.name }}</li>
: 对于每个用户,显示一个列表项,其中包含用户的姓名。{% empty %}
: 如果user_list
为空,则执行这个块中的内容。<li>空空如也</li>
: 在列表为空的情况下,显示一个包含文本 "空空如也" 的列表项。
这样,当 user_list
不为空时,会按照用户列表中的顺序显示每个用户的姓名;而当 user_list
为空时,会显示一个包含 "空空如也" 的列表项
<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% empty %}
<li>空空如也</li>
{% endfor %}
</ul>
6.2 if判断
6.2.1 if ~ elif ~ else
{% if user_list %}
用户人数:{{ user_list|length }}
{% elif black_list %}
黑名单数:{{ black_list|length }}
{% else %}
没有用户
{% endif %}
6.2.2 只有if和else
{% if user_list|length > 5 %}
七座豪华SUV
{% else %}
黄包车
{% endif %}
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
6.3 with
- 定义一个中间变量,多用于给一个复杂的变量起别名。
- 注意等号左右不要加空格。
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
- 或
{% with business.employees.count as total %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
6.4 csrf_token
- 这个标签用于跨站请求伪造保护。
- 在页面的form表单里面写上
6.5 注释
{# ... #}
6.6 注意事项
- Django的模板语言不支持连续判断,即不支持以下写法:
{% if a > b > c %}
...
{% endif %}
- 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的值。
6.7 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 %}
你好
我好
大家好
6.8 if语句示例
f = True
{% if f %}
<p>你好</p>
{% else %}
<p>我好</p>
{% endif %}
你好
6.9 混用 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 %}
第一次循环
我好
最后一次循环
7. 模版的继承
- 某些页面的整体大差不差,但是某一些局部在做变化
7.1 模板
<!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>
- 注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。
7.2 继承母板
- 在子页面中在页面最上方使用下面的语法来继承母板。
{% extends 'layouts.html' %}
7.3 块(block)
- 通过在母板中使用
{% block xxx %}
来定义"块"。 - 在子页面中通过定义母板中的block名来对应替换母板中相应的内容。
{% block page-main %}
<p>世情薄</p>
<p>人情恶</p>
<p>雨送黄昏花易落</p>
{% endblock %}
标签:知识点,return,name,模版,必备,list,html,user,def
From: https://www.cnblogs.com/Formerly/p/18102494