此处以DLT为例,DTL 是 Django Template Language 三个单词的缩写,也就是Django自带的模板语言。当然也可以配置Django支持Jinja2等其他模板引擎。
DTL模板是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。
渲染模板有两种常用的方式
①render_to_string:
找到模板,然后将模板编译后渲染成Python的字符串格式。最后再通过 HttpResponse 类包装成一个 HttpResponse 对象返回回去。示例代码如下:
from django.template.loader import render_to_string
from django.http import HttpResponse
def book_detail(request,book_id):
html = render_to_string("detail.html")
return HttpResponse(html)
②render:
django还提供了一个更加简便的方式,直接将模板渲染成字符串 和包装成 HttpResponse 对象一步到位完成。示例代码如下:
from django.shortcuts import render
def index(request):
return render(request, 'index.html')
在项目的 settings.py 文件中。有一个 TEMPLATES 配置,这个配置包含了模板引擎的配置,模板查找路径的配置,模板上下文的配置等。
当创建一个新的Django应用时,需要将该应用添加到INSTALLED_APPS列表中,这个列表中的每个应用程序都会被Django自动发现,并且可以使用Django的ORM、admin界面等功能。
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"home", # 要对自己的app进行安装
]
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates", # 模版引擎,可以换别的
"DIRS": [BASE_DIR / 'templates'], # 列表:存放所有的模板路径
"APP_DIRS": True, # 这个设置为True后,会在APP自己的templates文件夹中查找模板
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
普通变量:
{{ variable_name }}
访问。username = '哈哈'
可以在模板中用 {{ username }}
显示。字典类型:
.
)语法访问其键对应的值。game = {'name': '第五人格', 'character': '调香师'}
可以在模板中用 {{ game.name }}
或 {{ game.character }}
分别显示 '第五人格'
和 '调香师'
。列表:
.
)和数字表示。games = [{'name': '王者荣耀', 'character': '孙尚香'}, {'name': '原神', 'character': '宵宫'}]
可以在模板中用 {{ games.0 }}
访问第一个元素,用 {{ games.1.name }}
获取第二个元素中的 name
值。对象属性:
.
)语法访问。如果对象具有属性或无参数的方法,则可以直接在模板中使用该属性名或方法名。Person
类,并创建其实例 person = Person('小红')
,可以在模板中用 {{ person.realname }}
显示 '小红'
。注意事项
点(.
)语法解析顺序:
不支持中括号访问:Django 模板语言不支持像 dict['key']
或 list[1]
这样的中括号访问方式。
避免与内置属性名冲突:当向字典添加键时,要确保键名不会覆盖字典的内置方法或属性(如 items
, keys
等),否则会导致无法正常访问这些方法或属性。
# views.py
def info(request):
# 1. 普通的变量
username = '哈哈'
# 2. 字典类型
game = {'name': '第五人格', 'character': '调香师'}
# 3. 列表
games = [
{'name': '王者荣耀', 'character': '孙尚香'},
{'name': '原神', 'character': '宵宫'}
]
# return render(request, 'info.html', context={'username': username, 'game': game, 'games': games})
# 4.对象
class Person:
def __init__(self, realname):
self.realname = realname
context = {
'username': username,
'game': game,
'games': games,
'person': Person('小红')
}
return render(request, 'info.html', context=context)
# info.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>信息title>
head>
<body>
<p>{{ username }}p>
<p>游戏名称:{{ game.name }}p>
<p>下标为0的游戏:{{ games.0 }}p>
<p>下标为1的游戏的名称:{{ games.1.name }}p>
<p>姓名为:{{ person.realname }}p>
body>
html>
if
标签相当于 Python 中的 if
语句,有 elif
和 else
相对应,但是所有的标签都需要用标签符号 {% %}
进行包裹。 if
标签中可以使用 ==、!=、<、<=、>、>=、in、not in、is、is not
等判断运算符。
# if
def if_view(request):
age = 18
return render(request, 'if.html', context={'age': age})
{% if age > 18 %}
<p>您已满18岁。 可以玩第五人格p>
{% elif age == 18 %}
<p>您刚满18岁,需要先提交审核才能进入游戏p>
{% else %}
<p>您未满18岁,不可以玩第五人格p>
{% endif %}
for...in...
类似于 Python 中的 for...in...
。可以遍历列表、元组、字符串、字典等一切可以遍历的对象。
# for : 这里的for没有break和continue
def for_view(request):
# 1.列表
games = [
{'name': '王者荣耀', 'character': '孙尚香'},
{'name': '原神', 'character': '宵宫'},
{'name': 'lolm', 'character': '拉克丝'}
]
# 2.字典
person = {
'realname': 'KFC大王',
'age': 22,
'height': 190
}
context = {
'games': games,
'person': person
}
return render(request, 'for.html', context=context)
{#1.列表#}
<table>
<thead>
<tr>
<th>序号th>
<th>游戏名th>
<th>角色th>
tr>
thead>
<tbody>
{% for game in games reversed %} {#加reversed相当于反向遍历#}
<tr>
<td>{{ forloop.counter }}td>
<td>{{ game.name }}td>
<td>{{ game.character }}td>
tr>
{% endfor %}
tbody>
table>
{#2.字典 for in person.items/keys/values #}
<div>
{% for key, value in person.items %}
<p>{{ key }}:{{ value }}p>
{% empty %} {#在遍历的对象如果没有元素,会执行 empty 中的内容#}
<p>暂时没有用户p>
{% endfor %}
div>
在 for 循环中,DTL 提供了一些变量可供使用:
with
标签在模板中临时定义变量,从而简化复杂的表达式或重复使用的值
# with
def with_view(request):
context = {
'games': [
{'name': '王者荣耀', 'character': '孙尚香'},
{'name': '原神', 'character': '宵宫'},
{'name': 'lolm', 'character': '拉克丝'}
]
}
return render(request, 'with.html', context=context)
{% with ys=games.1 %}
{% with games.1 as ys %} {#写法二#}
<p>{{ ys.name }}:{{ ys.character }}p>
{% endwith %}
{%with%}{%endwith%}
中使用,不能在这个标签外面使用。{% with ys = games.1%}
是错误的。url
标签根据定义在 urls.py 文件中的 URL 模式反向解析出对应的 URL,使模板代码更加简洁和易于维护
# views.py
# url
def url_view(request):
return render(request, 'url.html')
# 用于url反转传参示例
def game_detail(request, game_id):
return HttpResponse(f'您访问的游戏id是:{game_id}')
# urls.py
urlpatterns = [
path('baidu', views.baidu, name='baidu'),
path('url', views.url_view, name="url"),
path('game/' , views.game_detail, name="game_detail"),
]
<a href="{% url 'baidu' %}">百度a>
# url反转,使用关键字参数
<a href="{% url 'game_detail' game_id=1 %}">游戏详情a>
# url反转,使用位置参数
<a href="{% url 'game_detail' 1 %}">游戏详情a>
更多标签请参考官方文档:https://docs.djangoproject.com/en/5.0/ref/templates/builtins/
过滤器名称 | 作用描述及注意点 |
---|---|
cut |
作用:移除指定的子串。 注意点:该过滤器直接从字符串中移除指定的所有实例,不支持正则表达式。 |
date |
作用:格式化日期时间。 注意点:需要确保传入的对象是日期或日期时间对象,否则会抛出错误。 |
default |
作用:提供默认值,如果变量为空或未定义则使用该值。 注意点:适用于字符串、列表等类型,但不会对布尔值 False 起作用。 |
safe |
作用:标记字符串为安全的,避免自动转义 HTML。 注意点:仅当您完全信任内容来源时使用,否则可能导致 XSS 攻击。 |
truncatechars |
作用:截断字符数到指定长度,并在末尾添加省略号(…)。 注意点:包括省略号在内的总长度将等于指定的字符数。 |
add |
作用:对两个参数执行加法操作。可应用于整数、浮点数、字符串和列表。 注意点:对于字符串,它会进行连接;对于列表,它会尝试拼接列表。不同类型的加法可能会导致意外结果。例如,数字与字符串相加会导致错误。 |
length |
作用:返回列表、元组、字典、字符串等的长度。 注意点:对于非迭代对象(如整数)将引发模板语法错误。 |
capfirst |
作用:将字符串的第一个字母转换为大写。 注意点:只影响第一个字母,其他字母不变。如果首字符不是字母,则保持原样。 |
lower |
作用:将字符串转换为小写。 注意点:只影响ASCII字符集中的大小写字母。 |
upper |
作用:将字符串转换为大写。 注意点:同样只影响ASCII字符集中的大小写字母。 |
slugify |
作用:将字符串转换为 URL 友好的格式(只包含小写字母、数字和连字符)。 注意点:会移除所有非字母数字字符,并将空格替换为连字符。 |
slice |
作用:对列表或字符串进行切片操作,类似于 Python 的切片语法。 注意点:切片索引必须有效,且不能超出范围。 |
join |
作用:使用指定的分隔符连接列表中的元素为一个字符串。 注意点:列表中的元素应为字符串,否则可能需要先转换。 |
random |
作用:从列表中随机选择一个元素。 注意点:每次渲染模板时都可能产生不同的输出。 |
escape |
作用:转义字符串中的 HTML 特殊字符。 注意点:用于防止 XSS 攻击,确保用户输入的安全性。 |
linebreaks |
作用:将换行符转换为 标签或 标签。注意点:适合处理多行文本,但在某些情况下,可能需要手动调整样式以适应布局需求。 |
striptags |
作用:去除所有 HTML 标签。 注意点:不会解析嵌套标签,简单地删除所有出现的标签。 |
# filter 过滤器
from datetime import datetime
def filter_view(request):
greet = 'I love you, you love me.'
items = ['apple', 'banana', 'cherry', 'date', 'elderberry']
text = "Hello Django!"
numbers = [1, 2, 3, 4, 5]
context = {
'greet': greet,
'today': datetime.now(),
'weather': '',
'html': '欢迎观看天气预报
',
'value': '北京欢迎您',
'number': 5,
'items': items,
'text': text,
'numbers': numbers,
}
return render(request, 'filter.html', context=context)
<p>{{ greet|cut:',' }}p>
<p>今天的日期:{{ today|date:'Y年m月d日' }}p>
<p>天气:{{ weather|default:'今天天气暂无,等待祭司预测' }}p>
<div>{{ html|safe }}div>
<div>{{ value|truncatechars:3 }}div>
<p>数字加2的结果:{{ number|add:2 }}p>
<p>列表项数量:{{ items|length }}p>
<p>首字母大写:{{ text|capfirst }}p>
<p>全部小写:{{ text|lower }}p>
<p>全部大写:{{ text|upper }}p>
<p>Slugified 文本:{{ text|slugify }}p>
<p>前三个水果:{{ items|slice:":3"|join:", " }}p>
<p>前五个字符:{{ text|slice:":5" }}p>
<p>水果列表(用逗号分隔):{{ items|join:", " }}p>
<p>随机水果:{{ items|random }}p>
<p>转义后的HTML:{{ html|escape }}p>
<p>带换行的文本:<pre>{{ "line1\nline2"|linebreaks }}pre>p>
<p>去除HTML标签后的文本:{{ html|striptags }}p>