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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n