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

2024-02-24 10:44

本文主要是介绍精通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应用。继续深入学习和实践,开拓更广阔的技术领域吧!

这篇关于精通Django模板(模板语法、继承、融合与Jinja2语法的应用指南)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741855

相关文章

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Java利用Spire.Doc for Java实现在模板的基础上创建Word文档

《Java利用Spire.DocforJava实现在模板的基础上创建Word文档》在日常开发中,我们经常需要根据特定数据动态生成Word文档,本文将深入探讨如何利用强大的Java库Spire.Do... 目录1. Spire.Doc for Java 库介绍与安装特点与优势Maven 依赖配置2. 通过替换

Java 队列Queue从原理到实战指南

《Java队列Queue从原理到实战指南》本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效... 目录一、队列的认识队列的底层与集合框架常见的队列方法插入元素方法对比(add和offer)移除元素方法

Spring Boot基于 JWT 优化 Spring Security 无状态登录实战指南

《SpringBoot基于JWT优化SpringSecurity无状态登录实战指南》本文介绍如何使用JWT优化SpringSecurity实现无状态登录,提高接口安全性,并通过实际操作步骤... 目录Spring Boot 实战:基于 JWT 优化 Spring Security 无状态登录一、先搞懂:为什

Nginx概念、架构、配置与虚拟主机实战操作指南

《Nginx概念、架构、配置与虚拟主机实战操作指南》Nginx是一个高性能的HTTP服务器、反向代理服务器、负载均衡器和IMAP/POP3/SMTP代理服务器,它支持高并发连接,资源占用低,功能全面且... 目录Nginx 深度解析:概念、架构、配置与虚拟主机实战一、Nginx 的概念二、Nginx 的特点

C#实现插入与删除Word文档目录的完整指南

《C#实现插入与删除Word文档目录的完整指南》在日常的办公自动化或文档处理场景中,Word文档的目录扮演着至关重要的角色,本文将深入探讨如何利用强大的第三方库Spire.Docfor.NET,在C#... 目录Spire.Doc for .NET 库:Word 文档处理利器自动化生成:C# 插入 Word

Python列表去重的9种方法终极指南

《Python列表去重的9种方法终极指南》在Python开发中,列表去重是一个常见需求,尤其当需要保留元素原始顺序时,本文为大家详细介绍了Python列表去重的9种方法,感兴趣的小伙伴可以了解下... 目录第一章:python列表去重保持顺序方法概述使用字典去重(Python 3.7+)使用集合辅助遍历性能

Nginx内置变量应用场景分析

《Nginx内置变量应用场景分析》Nginx内置变量速查表,涵盖请求URI、客户端信息、服务器信息、文件路径、响应与性能等类别,这篇文章给大家介绍Nginx内置变量应用场景分析,感兴趣的朋友跟随小编一... 目录1. Nginx 内置变量速查表2. 核心变量详解与应用场景3. 实际应用举例4. 注意事项Ng

在SpringBoot+MyBatis项目中实现MySQL读写分离的实战指南

《在SpringBoot+MyBatis项目中实现MySQL读写分离的实战指南》在SpringBoot和MyBatis项目中实现MySQL读写分离,主要有两种思路:一种是在应用层通过代码和配置手动控制... 目录如何选择实现方案核心实现:应用层手动分离实施中的关键问题与解决方案总结在Spring Boot和