精通Django模板(模板语法、继承、融合与Jinja2语法的应用指南)

模板:

基础知识:

​ 在Django框架中,模板是可以帮助开发者快速⽣成呈现给⽤户⻚⾯的⼯具模板的设计⽅式实现了我们MVT中VT的解耦(M: Model, V:View, T:Template),VT有着N:M的关系,⼀个V可以调⽤任意T,⼀个T可以供任意V使⽤ (MVC: Model,View界⾯,Controller控制器)。

模板处理分为两个过程

  • 加载HTML

  • 渲染数据 render()

模板主要有两个部分

  • HTML静态代码

  • 模板语⾔,动态插⼊的代码段(挖坑,填坑)

模板中的动态代码段除了做基本的静态填充,还可以实现⼀些基本的运算,转换和逻辑

页面分类:

  • 静态⻚⾯:⻚⾯数据是本地固定的

  • 动态⻚⾯:⻚⾯数据来源于后台服务器


模板中的变量: 视图传递给模板的数据,遵守标识符规则语法: {{ var }}
如果变量不存在,则插⼊空字符串。

在这里插入图片描述

⽅法不能有参数。
{{ str }}
{{ str.upper }}
{{ str.isdigit }}
{{ dict.key }}
列表,使⽤索引,不允许负索引
items= ['apples', 'bananas', 'carrots']
{{ items.2 }}

标签语句:

模板中的标签语法 {% tag %}作⽤1.加载外部传⼊的变量2.在输出中创建⽂本3.控制循环或逻辑

条件语句:

 if 语句: 格式:if单分⽀{% if 表达式 %}语句{% endif %} if双分⽀{% if 表达式 %}语句{% else %}语句{% endif %}if多分⽀{% if 表达式 %}语句{% elif 表达式 %}语句{% else %}语句{% endif %}判断true或false{% if today_is_weekend %}<p>Welcome to the weekend!</p>{% endif %}

与或运算:

    使⽤ and or not{% if athlete_list and coach_list %}<p>Both athletes and coaches are available.</p>{% endif %}{% if not athlete_list %}<p>There are no athletes.</p>{% endif %}{% if athlete_list or coach_list %}<p>There are some athletes or some coaches.</p>{% endif %}使⽤ in和not in,{% if "bc" in "abcdef" %}This appears since "bc" is a substring of "abcdef"{% endif %}{% if user not in users %}If users is a list, this will appear if user isn't an element of the list.{% endif %}

for循环:

for 语句:{% for 变量 in 列表 %}语句1{% empty %}语句2{% endfor %}当列表为空或不存在时,执⾏empty之后的语句
{{ forloop.counter }} 表示当前是第⼏次循环,从1数数{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{%endfor %}{{ forloop.counter0}}表示当前是第⼏次循环,从0数数
{{ forloop.revcounter}}表示当前是第⼏次循环,倒着数数,到1停
{{ forloop.revcounter0}}表示当前第⼏次循环,倒着数,到0停
{{ forloop.first }} 是否是第⼀个	布尔值{% for object in objects %}{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}{{ object }}</li>
{% endfor %}{{ forloop.last }} 是否是最后⼀个 布尔值
{% for link in links %}
{{ link }}{% if not forloop.last %} | {% endif %}
{% endfor %}forloop.parentloop
{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.parentloop.counter }}</td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}

注释:

注释:单⾏注释{# 被注释掉的内容	#}多⾏注释{% comment %}内容{% endcomment %}

过滤器:

过滤器:{{ var|过滤器 }}作⽤:在变量显示前修改add {{ value|add:2 }}没有减法过滤器,但是加法⾥可以加负数{{ value|add:-2 }} lower{{ name|lower }} upper{{ my_list|first|upper }} my_list 第一个值变成大写 截断:{{ bio|truncatechars:30 }}过滤器可以传递参数,参数需要使⽤引号引起来⽐如join: {{ students|join:'=' }}默认值:default,格式 {{var|default:value}}如果变量没有被提供或者为False,空,会使⽤默认值根据指定格式转换⽇期为字符串,处理时间的就是针对date进⾏的转换{{ dateVal | date:'y-m-d' }}

转义:

HTML转义将接收到的数据当成普通字符串处理还是当成HTML代码来渲染的⼀个问题渲染成html:{{ code|safe }}关闭⾃动转义{% autoescape off%} code{% endautoescape %}打开⾃动转义转义{% autoescape on%} code{% endautoescape %}
案例讲解:

App.views.py

from django.shortcuts import render# Create your views here.
import datetimefrom django.shortcuts import render# 模板
def index(request):data = {'name': 'zhangsan','age': 3,'likes': ['movie', 'game', 'code'],'address': {'city': '深圳', 'province': '广东'},'stars': [['化mm', 'mm云', 'mm克'],['x军', 'mm宏', '一鸣'],['伯格', 'mm茨', 'mm非'],],'dt': datetime.datetime.now(),'code': '<b>I am a good man</b>','code2': '''<script>var n=3;while(n--) {alert('哈哈')}</script>''',}# 下面的写法都可以# return render(request, 'index.html', {**data}) return render(request, 'index.html', data)# 模板继承
# 父模板
def block(request):return render(request, 'block.html')# 子模板
def child(request):return render(request, 'child.html')# 使用模板(HTML+模板语言): 前后端不分离

项目工程下的urls.py

from django.contrib import admin
from django.urls import path
from App.views import *urlpatterns = [path('index/', index),path('block/', block),path('child/', child),path('admin/', admin.site.urls),
]

传参细节:

# 用户列表
def user_list(request):# 获取所有用户数据users = UserModel.objects.all()return render(request, 'user_list.html', {'users': users})

这个是我们之前的写法,相当于传递了一个字典,这是因为数据量比较少,如果数据量比较多,就不能这样传递了,如下:

# 模板
def index(request):data = {'name': 'zhangsan','age': 3,'likes': ['movie', 'game', 'code'],'address': {'city': '深圳', 'province': '广东'},'stars': [['化mm', 'mm云', 'mm克'],['x军', 'mm宏', '一鸣'],['伯格', 'mm茨', 'mm非'],],'dt': datetime.datetime.now(),'code': '<b>I am a good man</b>','code2': '''<script>var n=3;while(n--) {alert('哈哈')}</script>''',}return render(request, 'index.html', data) # 这个就是传递的字典

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Django模板</title>
</head>
<body><h2>Django模板</h2><hr>{#  单行注释  #}{% comment %}多行注释多行注释{% endcomment %}{#   变量     #}<p>name: {{ name }}</p><p>age: {{ age }}</p>{# 处理列表,使用 .  # }<p>likes: {{ likes }}</p><p>likes.1: {{ likes.1 }}</p>{# 字典 键值对 #}<p>address: {{ address }}</p><p>address.city: {{ address.city }}</p><hr><br><br><br><br><br><br><br><br><br><br></body>
</html>

在这里插入图片描述

{#   标签     #}<h3>if语句</h3><h4>if单分支</h4>{% if age < 18 %}<p>{{ name }} 未成年 </p>{% endif %}<h4>if双分支</h4>{% if age < 18 %}<p>{{ name }} 未成年 </p>{% else %}<p>{{ name }} 成年了! </p>{% endif %}<h4>if多分支</h4>{% if age < 18 %}<p>{{ name }} 未成年 </p>{% elif age < 60 %}<p>{{ name }} 是壮年 </p>{% else %}<p>{{ name }} 老年人 </p>{% endif %}<h4>结合运算符</h4>{% if age >= 18 and age < 60 %}<p>{{ name }} 是壮年,风华正茂,小年轻! </p>{% endif %}{% if age < 18 or age >= 60 %}<p>{{ name }} 未成年或者是老年人! </p>{% endif %}{% if 'movie' in likes %}<p> {{ name }} 喜欢movie! </p>{% endif %}<hr>

在这里插入图片描述

 <h3>for循环语句</h3>{% for like in likes %}<p>{{ like }}</p>{% endfor %}<h4>empty</h4>{% for like in likes2 %}<p>{{ like }}</p>{% empty %}<p>likes2 为空或者不存在</p>{% endfor %}<h4>下标</h4>{% for like in likes %}<p>counter0: {{ forloop.counter0 }},counter: {{ forloop.counter }},revcounter0: {{ forloop.revcounter0 }},revcounter: {{ forloop.revcounter }},{% if forloop.first %}<b> - first</b>{% endif %}{% if forloop.last %}<b> - last</b>{% endif %}</p>{% endfor %}<h4>循环嵌套</h4>{#{{ forloop.parentloop 是父亲循环 # }<table border="1" width="400">{% for star in stars %}<tr>{% for s in star %}<td>{{ s }}-{{ forloop.parentloop.counter }} -{{ forloop.counter }}</td>{% endfor %}</tr>{% endfor %}</table>

在这里插入图片描述

    <h4>过滤器</h4><p>age = {{ age }}</p><p>age|add:2 = {{ age|add:2  }}</p><p>age|add:-2 = {{ age|add:-2  }}</p><p>name = {{ name }}</p><p>name|last|lower 是将第一个字符取出来 变成大小写 </p> <p>name|first|upper = {{ name|first|upper }}</p><p>name|last|lower = {{ name|last|lower }}</p><p>title 首字母大写 </p><p>name|title = {{ name|title }}</p><p>truncatechars 截断</p><p>name|truncatechars:7 = {{ name|truncatechars:7 }}</p><p>likes = {{ likes }}</p><p> likes|join:'+'  字符串拼接 </p><p>likes|join:'+' = {{ likes|join:'+' }}</p><p>likes2 = {{ likes2 }}</p><p> default 表示默认值 </p> <p>likes2|default:'swim' = {{ likes2|default:'swim' }}</p><p>日期格式化 </p><p>dt = {{ dt }}</p><p>dt = {{ dt|date:'y-m-d' }}</p><p>dt = {{ dt|date:'Y-m-d' }}</p>

在这里插入图片描述

   <h5>html解析</h5><p>code|safe  表示对其html做解析,也可以执行js</p><p>code = {{ code }}</p><p>code|safe = {{ code|safe }}</p><p>code2 = {{ code2 }}</p>
{#    <p>code2 = {{ code2|safe }}</p> #}{% autoescape on %}{{ code }}{% endautoescape %}

在这里插入图片描述

模板继承:

基础知识:

模板继承block:{% block XXX%} code{% endblock %}extends 继承,写在开头位置{% extends '⽗模板路径' %}include: 加载模板进⾏渲染{% include '模板⽂件' %}{{ block.super }} : 获取⽗模板中block中的内容

view.py

# 模板继承
# 父模板
def block(request):return render(request, 'block.html')# 子模板
def child(request):return render(request, 'child.html')

urls.py

from django.contrib import admin
from django.urls import path
from App.views import *urlpatterns = [path('index/', index),path('block/', block),path('child/', child),path('admin/', admin.site.urls),
]

父模板:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>{#  css  #}{% block extcss %}{% endblock %}</head>
<body><h2>父模板</h2><hr>{% block head %}{% endblock %}<hr>{% block content %}<button>我是Content父模板中的按钮</button>{% endblock %}<hr>{% block foot %}{% endblock %}{#  js  #}{% block extjs %}{% endblock %}</body>
</html>

在这里插入图片描述

自带只需要对父模板进行填充block即可。

{# 继承父模板 #}
{% extends 'block.html' %}{% block head %}<div><button>Head</button></div>
{% endblock %}{% block content %}{#  默认情况下,子模板会覆盖父模板的内容  #}{# 如果想将父模板中block的内容继承,则需要使用block.super #}{{ block.super }}<div><button>Content</button></div>
{% endblock %}{% block foot %}<div><button>Foot</button></div>{#  导入其他模板文件  #}{% include 'child_include.html' %}{% endblock %}

在这里插入图片描述

注意:子模版会默认覆盖父模板,如果想将内容继承过来,则需要使用 {{ block.super }}.

jinja2:

在Django项⽬中使⽤Jinja2模板引擎,Jinja2是之前我们在Flask框架讲过的⼀个模板引擎,是模仿Django默认模板引擎基础上开发的,⽐Django模板引 擎性能更好,功能更全.
jinja2宣称⽐django默认模板引擎快10-20倍。Django也⽀持jinja2

首先需要安装jinja2:

pip install jinja2 -i https://pypi.tuna.tsinghua.edu.cn/simple/

在这里插入图片描述

在这里插入图片描述

from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environmentdef environment(**options):env = Environment(**options)env.globals.update({'static': static,'url': reverse,})return env

在setting.py做修改:

TEMPLATES = [{"BACKEND": 'django.template.backends.jinja2.Jinja2',"DIRS": [BASE_DIR / 'templates'],"APP_DIRS": True,"OPTIONS": {# 这⾥要添加environment,并指定到jinja2_env⽂件中的environment'environment': 'demo2.jinja2_env.environment',"context_processors": ["django.template.context_processors.debug","django.template.context_processors.request","django.contrib.auth.context_processors.auth","django.contrib.messages.context_processors.messages",],},},# 原来自带的Django模板引擎{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [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',],},},
]

在这里插入图片描述

修改模板语言提示配置:

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h2>Jinja2模板语言</h2><hr><p>name: {{ name }}</p>{% for n in name %}<b>{{ n }}</b>{% endfor %}<hr>{#  不能使用Django语法了   #}{% for n in name %}<div>{{ loop.index }}:{{ n }}</div>{% endfor %}<hr>{#  Jinja2 是可以使用函数调用  #}{% for i in range(1, 4) %}<div>{{ i }}</div>{% endfor %}</body>
</html>

在这里插入图片描述

注意:

在Flask中,传递参数使用关键词传递参数,而Django使用字典传参数。

views.py

from django.shortcuts import render# Create your views here.def index(request):return render(request, 'index.html', {'name': 'zhangsan'})

总结:

通过本文的详细讲解,我们对Django模板的基础知识有了全面的了解。从如何在HTML中显示数据、使用循环和判断语句、应用过滤器等等,我们掌握了丰富的技巧和技能。同时,我们也学习了模板的继承与融合,为构建复杂而灵活的网页奠定了基础。

此外,我们还介绍了如何在Django中配置使用Jinja2语法,为开发者提供了更多的选择和灵感。通过灵活运用这些工具和技术,我们能够创建出更加强大、美观且可维护的Web应用程序。

希望本文能对读者在学习和使用Django模板时提供帮助。掌握了这些知识和技巧,相信你能够更加高效地开发出出色的Web应用。继续深入学习和实践,开拓更广阔的技术领域吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/698011.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度地图海量点方案趟坑记录(百度地图GL版 + MapVGL + vue3 + ts)

核心需求描述 不同层级有不同的海量图标展示底层海量图标需要展示文字拖动、放大缩小都需要重新请求数据并展示固定地图中心点&#xff08;拖动、放大缩小&#xff0c;中心点始终在地图中心&#xff09; 示例图片&#xff1a;&#xff08;某些图片涉及公司数据&#xff0c;就未…

基础数据结构和算法《》

递归 1.递归应该一种比较常见的实现一些特殊代码逻辑时需要做的&#xff0c;但常常也是最绕的一种方式&#xff0c;在解释递归 之前&#xff0c;我们用循环和递归来做个比较1.1.如果你打开一扇门后&#xff0c;同样发现前方也有一扇们&#xff0c;紧接着你又打开下一扇门...直…

备战蓝桥杯---基础算法刷题1

最近在忙学校官网上的题&#xff0c;就借此记录分享一下有价值的题&#xff1a; 1.注意枚举角度 如果我们就对于不同的k常规的枚举&#xff0c;复杂度直接炸了。 于是我们考虑换一个角度&#xff0c;我们不妨从1开始枚举因子&#xff0c;我们记录下他的倍数的个数sum个&#…

Android platform tool中d8.bat不生效

d8.bat因找不到java_exe文件&#xff0c;触发EOF d8.bat中之前代码为&#xff1a; set java_exe if exist "%~dp0..\tools\lib\find_java.bat" call "%~dp0..\tools\lib\find_java.bat" if exist "%~dp0..\..\tools\lib\find_java.bat" …

分享一个我爱工具网源码优化版

应用介绍 本文来自&#xff1a;分享一个我爱工具网源码优化版 - 源码1688 前几天在网上看到了一个不错的工具网源码&#xff0c;但是源码存在一些问题&#xff0c;遂进行了修改优化。 主要修改内容有&#xff1a; 1、后台改为账号密码登录&#xff0c;上传即用&#xff0c;不…

前后端延迟怎么解决

当今互联网应用的发展越来越迅猛&#xff0c;用户对于网站或应用的性能要求也越来越高。其中一个重要方面就是前后端延迟的解决&#xff0c;也就是减少前端与后端之间的通信时间延迟&#xff0c;提高用户体验。本文将详细介绍如何解决前后端延迟的问题。 网络延迟 数据在网络…

【DAY03 软考中级备考笔记】存储系统,总线系统,输入输出系统和可靠性

存储系统&#xff0c;总线系统&#xff0c;输入输出系统和可靠性 2月22日 – 天气&#xff1a;阴转晴 济南下大雪&#xff0c;居家办公两天。 1. 计算机存储器的分类 根据存储位置划分&#xff1a; 内存/主存&#xff1a;用来保存当前正在运行的程序所需要的数据&#xff0c…

【C++精简版回顾】6.构造函数

一。类的四种初始化方式 1.不使用构造函数初始化类 使用函数引用来初始化类 class MM { public:string& getname() {return name;}int& getage() {return age;}void print() {cout << "name: " << name << endl << "age: &quo…

React学习——快速上手

文章目录 初步模块思维 初步 https://php.cn/faq/400956.html 1、可以手动使用npm来安装各种插件&#xff0c;来从头到尾自己搭建环境。 如&#xff1a; npm install react react-dom --save npm install babel babel-loader babel-core babel-preset-es2015 babel-preset-rea…

3.测试教程 - 基础篇

文章目录 软件测试的生命周期软件测试&软件开发生命周期如何描述一个bug如何定义bug的级别bug的生命周期如何开始第一次测试测试的执行和BUG管理产生争执怎么办&#xff08;处理人际关系&#xff09; 大家好&#xff0c;我是晓星航。今天为大家带来的是 测试基础 相关的讲解…

防火墙内容安全笔记

目录 DFI和DPI IDS和IPS 签名 AV URL过滤 HTTPS过滤 内容过滤 文件类型过滤 文件内容过滤 邮件过滤 VPN概述 密码学概述 对称加密 非对称加密 DFI和DPI DFI和DPI技术 --- 深度检测技术 DPI DPI --- 深度包检测技术 --- 主要针对完整的数据包&#xff08;数据包…

【springBoot】springAOP

AOP的概述 AOP是面向切面编程。切面就是指某一类特定的问题&#xff0c;所以AOP也可以理解为面向特定方法编程。AOP是一种思想&#xff0c;拦截器&#xff0c;统一数据返回和统一异常处理是AOP思想的一种实现。简单来说&#xff1a;AOP是一种思想&#xff0c;对某一类事务的集…

Camtasia2024官方标准版重磅发布更新及新版本功能介绍

Camtasia 2024标准版是一款功能强大的屏幕录制和视频编辑软件。它继承了Camtasia系列一贯的易用性和丰富功能&#xff0c;为用户提供了高效、专业的视频制作体验。 在屏幕录制方面&#xff0c;Camtasia 2024标准版支持录制电脑屏幕上的任何内容&#xff0c;包括网站、软件、视…

9、内网安全-横向移动Exchange服务有账户CVE漏洞无账户口令爆破

用途&#xff1a;个人学习笔记&#xff0c;有所借鉴&#xff0c;欢迎指正&#xff01; 背景&#xff1a; 在内网环境的主机中&#xff0c;大部分部署有Exchange邮件服务&#xff0c;对于Exchange服务的漏洞也是频出&#xff0c;在这种情况下&#xff0c;如果拿到内网中一台主机…

harbor(docker仓库)仓库部署 - 高可用

harbor&#xff08;docker仓库&#xff09;仓库部署 - 高可用 1. harbor高可用1.1 方案说明1. 双主复制2. 多harbor实例共享后端存储 1.2 部署高可用&#xff08;多harbor实例共享后端存储&#xff09;1. 服务器划分2. 安装harbor&#xff08;先部署一套Harbor&#xff0c;用于…

PostgreSQL与MySQL,谁更胜一筹

前言 PostgreSQL与MySQL都是优秀的开源数据库。在日常学习中&#xff0c;新手可能接触最多的是MySql,但是实际工作中&#xff0c;两者的应用场景其实都很广。我之前的做过上网流量销售业务&#xff0c;用的是MySQL,现在接触广告业务&#xff0c;用的是pg数据库&#xff0c;每天…

深入理解 v-for 中 key 的重要性

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

【k8s核心概念与专业术语】

k8s架构 1、服务的分类 服务分类按如下图根据数据服务支撑&#xff0c;分为无状态和有状态 无状态引用如下所示&#xff0c;如果一个nginx服务&#xff0c;删除后重新部署有可以访问&#xff0c;这个属于无状态&#xff0c;不涉及到数据存储。 有状态服务&#xff0c;如redis&a…

RF 框架实现企业级 UI 自动化测试

RobotFramework 框架可以作为公司要做自动化 但是又不会代码的一种临时和紧急情况的替代方案&#xff0c;上手简单。 前言 现在大家去找工作&#xff0c;反馈回来的基本上自动化测试都是刚需&#xff01;没有自动化测试技能&#xff0c;纯手工测试基本没有什么市场。 但是很多…

探究全链路压力测试的含义与重要性

全链路压力测试是指对整个应用系统的各个环节或组件进行压力测试&#xff0c;以模拟实际生产环境中的用户负载和流量&#xff0c;评估系统在高负载条件下的性能表现。 1. 全链路压力测试的含义 全链路压力测试涉及系统的所有组件和环节&#xff0c;包括前端用户界面、应用服务器…