精通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

相关文章

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

Python使用qrcode库实现生成二维码的操作指南

《Python使用qrcode库实现生成二维码的操作指南》二维码是一种广泛使用的二维条码,因其高效的数据存储能力和易于扫描的特点,广泛应用于支付、身份验证、营销推广等领域,Pythonqrcode库是... 目录一、安装 python qrcode 库二、基本使用方法1. 生成简单二维码2. 生成带 Log

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

将Python应用部署到生产环境的小技巧分享

《将Python应用部署到生产环境的小技巧分享》文章主要讲述了在将Python应用程序部署到生产环境之前,需要进行的准备工作和最佳实践,包括心态调整、代码审查、测试覆盖率提升、配置文件优化、日志记录完... 目录部署前夜:从开发到生产的心理准备与检查清单环境搭建:打造稳固的应用运行平台自动化流水线:让部署像

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

基于Java实现模板填充Word

《基于Java实现模板填充Word》这篇文章主要为大家详细介绍了如何用Java实现按产品经理提供的Word模板填充数据,并以word或pdf形式导出,有需要的小伙伴可以参考一下... Java实现按模板填充wor编程d本文讲解的需求是:我们需要把数据库中的某些数据按照 产品经理提供的 word模板,把数据

Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南

《Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南》在日常数据处理工作中,我们经常需要将不同Excel文档中的数据整合到一个新的DataFrame中,以便进行进一步... 目录一、准备工作二、读取Excel文件三、数据叠加四、处理重复数据(可选)五、保存新DataFram