【python】Django系列08-Django中的模板(续)

🙋作者:爱编程的小贤
⛳知识点:Django–模板语言
🥇:每天学一点,早日成大佬


👊前言

💎 💎 💎今天我们进入Django模板第二讲模板语言的学习啦!!! 😁 😁 😁 学习之前先要好好复习回顾前面的内容哦!!!
如果你看完感觉对你有帮助,,,欢迎给个三连哦💗!!!您的支持是我创作的动力。🌹 🌹🌹 🌹 🌹 🌹 感谢感谢!!!😘😘😘

🚀模板语言

模板语言主要包括变量(Variables)、标签(Tags)、过滤器(Filters)和注释(Comments)四部分。

1.变量

在模板中变量是使用{{变量}}来体现的,它的值放在上下文对象(context)中,上下文对象中可能存在很多变量,这些变量以类似字典的形式存放。变量名可以包括字母数字下划线,但是绝对不可以包括空格其它标点符号。英文句点’.'在变量中有特殊意义,如果模板引擎遇到了句点,将会按照下面的顺序对其进行解释。

  • 字典查找: {{ my_dict.key }}。
  • 查找属性和方法: {{ my_object.attribute }}。
  • 查找下标: {{my_list.0 }}。

注意:如果句点后面的变量是一个方法,那么这个方法会按照空参数的方式调用。例如一个字典的iteritems方法可以在模板中用以下方式调用:

{% for k, v in defaultdict.items %} 
	Do something with k and v here... 
{% endfor %}

2.注释

2.1单行注释

{# ... #}

2.2多行注释

{ % comment "Optional note" % } 
	... 
{ % endcomment % }

注意:多行注释的comment标签不能嵌套使用

3.标签

3.1用法

类似于{% tag %}。相对于变量来说标签更加复杂,标签可以用于输出文本、控制代码逻辑等。
有些标签还需要有开始标记和结束标记,这类标签的格式类似于{% tag %}···{% endtag %}。

Django中有20多种标签,详情可见参考官方文档。

👉官方文档

3.2常用标签

1. block 用于定义一个模板块,这个模板块能够被子模板重写,用法如下: 
{% block 模板块的名字 %} ... {% endblock %} 


2. extends 用于标记当前模板继承自哪个父模板。
注意:必须写在模板文件的第一行,哪怕前面是注释也不行 
{% extends "base.html" %}


3. comment 模板中的注释,模板引擎将会忽略
{% comment %}{% endcomment %}之间的任何代码。


4. for 循环遍历一个可迭代对象 
例如下面代码,使用for循环生成一个无序列表: 
<ul>
	{% for athlete in athlete_list %} 
		<li>{{ athlete.name }}</li> 
	{% endfor %} 
</ul> 

还可以用reversed对列表进行翻转: 
{% for obj in list reversed %} 
{% endfor %} 

使用for循环遍历字典 
{% for key, value in data.items %} 
	{{ key }}: {{ value }} 
{% endfor %} 

for循环还提供了一些变量,如下所示:
 forloop.counter: 返回当前循环位置(以数字1位起始) 
 forloop.counter0: 返回当前循环位置(以数字0位起始) 
 forloop.revcounter: 反向循环位置(列表的最后一位是1,列表第一位是n) 
 forloop.revcounter0: 反向循环位置(列表的最后一位是0,列表第一位是n-1) 
 forloop.first: 如果是当前循环的第一位,则返回True 
 forloop.last: 如果是当前循环的最后一位,则返回False 
 forloop.parentloop: 上级循环 


5. for...empty 当被遍历对象为空时,显示empty标签内容,其它部分与for循环一致。 
代码示例: 
<ul> 
	{% for athlete in athlete_list %} 
		<li> {{ athlete.name }} </li> 
	{% empty %} 
		<li>Sorry, no athletes in this list.</li> 
	{% endfor %} 
</ul> 


6. if 条件判断标签,当判断条件为真时(存在、非空、非False值)输出标签内容。与Python一样,if标签也支 持elifelse条件分支语句。
代码示例: 
{% if ... %} 
	... 
{% elif ... %} 
	... 
{% else %} 
	... 

同样if标签还支持对判断条件进行逻辑运算,逻辑运算包括andornot{% if A and B %} 
	... 
{% endif %} 

注意:不能在if标签中使用圆括号对判断条件进行分组,如以下代码将会抛出“Could not parse the remainder:'(False'from'(False'”错误: 
{% if numbers and (False or True) %} 
	pass 
{% endif %} 

除了逻辑运算符外,if标签还支持的运算符包括:==!=<><=>=innot inisis not。 用法同python 

**注意:运算符与变量之间必须要有空格隔开**


7. with 为复杂变量创建别名,尤其是使用句点访问多级变量时非常方便: 
{% with total=business.employees.count %} 
	{{ total }} employee {{ total|plurlaize }} 
{% endwith %} 
.....

3.3人性化语义标签

除上述功能性标签外,Django还提供了很多辅助性的标签,这些标签只是为了使变量输出变得更加可 读,下面对这些标签进行简单介绍。
首先,在使用这些标签之前,需要在INSTALLED_APPS中注册"django.contrib.humanize",然后在模板 中引用{% load humanize %}就可以了

1. apnumber 
将数字1~9转换为对应的单词,但是其他数字不转换,如数字10将被原样输出。 示例: 数字1将被转换为one。 
数字2将被转换为two。 数字10仍显示10。 
如果当前工程语言是中文,数字将会被转换为对应的汉字,例如: {{1|apnumber}} --> '一' 
{{2|apnumber}} --> '二' 
{{3|apnumber}} --> '三' 
{{10|apnumber}} --> '10' 


2. intcomma输出以逗号分隔的数字,例如: 
{{ 4500|intcomma}} --> '4,500' 
{{ 4500.2|intcomma }} --> '4500.2' 
需要注意的是,如果当前语言不支持以逗号分隔数值类型,那么intcomma将不会生效,
如当 LANGUAGE_CODE='zh-hans'时数值类型将原样显示. 


3. intword 
以可读性较高的文字形式输出超大的数字,如1000000输出“1.0 million” 


4.naturalday 
将当前日期以及前后一天分别输出为“today” “yesterday” “tomorrow”,
中文系统分别输出“今天” “昨天” “明天”。

 ....

3.4自定义标签

在Django中,可以通过一些快捷方式来帮助开发人员快速开发自定义标签。 其中,simple_tag()是最简单的一类快捷方式,如下所示:

django.template.Library.simple_tag()

很多标签的工作就是接收一些参数并简单运算,最后返回运算结果,对于这种类型的标签可以使用simple_tag进行开发。

下面以格式化输出当前日期为例,查看如何使用simple_tag,在这之前需要在子应用中创建一个名为 templatetags的文件夹,并且在文件夹中创建两个py文件 __init__和 mytags.py,在mytags.py文件中编
写以下代码,创建__init__文件确保了这个目录被视作一个python包

import datetime 
from django import template 

register = template.Library() 

@register.simple_tag 
def current_time(format_string): 
	return datetime.datetime.now().strftime(format_string) 

#模板中: 
{% load current_time %}
{% current_time "%y-%m-%d" %}

4.过滤器

4.1作用

过滤器可以用来修改变量的显示样式。

4.2使用方式

{{ 变量|过滤器方法 }}。过滤器可以连续使用,形式如:{{变量|过滤器方法1|过滤器方法2}}。
如果过滤器需要参数,则使用冒号’:'传递参数。形式如:{{变量|过滤器:‘参数’}}

注意:变量、管道符(’|’)和过滤器方法之间不能有空格

列举如下:

  • safe,禁用转义,告诉模板这个变量是安全的,可以解释执行
  • lenth,长度,返回字符串包含字符的个数,或列表、元祖、字典的元素个数。
  • default,默认值,如果变量不存在时则返回默认值。
data|default:'默认值'
  • date,日期,用关于对日期类型的值进行字符串格式化,常用的格式化字符如下:

    • Y表示年,格式为4位,y表示两位的年。
    • m表示月,格式为01,02,12等。
    • d表示日,格式为01,02等。
    • j表示日,格式为1,2等
    • H表示时,为24小时制,
    • h表示12小时制。
    • i表示分,为0-59。 s表示秒,为0-59。
value|date:"Y年m月j日 H时i分s秒"

4.3自定义过滤器

自定义过滤器就是一个可以接受一个或者多个参数的python方法。

  • 接收的变量可以是任意类型,并不局限于字符串。
  • 过滤器方法的参数可以有默认值。

例如,在过滤器{{var|foo:“bar”}}中,foo同时接收变量var和参数bar。
由于模板语言不能处理异常,因此在过滤器方法中出现的异常都会成为服务器异常,应该避免过滤器方法中出现的异常情况。

下面是一个自定义过滤器的代码示例:

def cut(value, arg): 
	"""从字符串value中删除所有的arg""" 
	return value.replace(arg, '')

下面为过滤器cut的使用方法:

{{somevariable|cut:"0"}}

大多数过滤器并不接受参数,这类过滤器的写法类似于:

def lower(value): 
	return value.lower()

编写完自定义过滤器方法后,需要使用Library实例对其进行注册,否则不能使用,注册代码如下:

register.filter('cut', cut) 
register.filter('lower', lower)

Library.filter()方法接收两个参数:

  • 第一个参数为过滤器的名字(字符串类型)
  • 第二个参数为过滤器方法。

除了使用Library.filter()方法注册过滤器外,还可以使用装饰器注册标签和过滤器,例如:

@register.filter(name='cut')
def cut(value, arg): 
 	return value.replace(arg, '') 

@register.filter(name='lower') 
def lower(value): 
	return value.lower()

注意:如果省略name参数,Django将会使用函数名作为过滤器名字。
如果需要限制过滤器接收的变量(即value参数)只能是字符串,可以使用stringfilter方法属性,例如:

from django import template 
from django.template defaultfilters import stringfilter 

register = template.Library()
 
@register.filter 
@stringfilter 
def blogtrans(value, unit): 
	return value.lower() + unit

使用该过滤器:

{% load blogtrans %} 
{{ 4|blogtrans:"$" }} 
{{ '10'|blogtrans:'¥' }}

此时即使给过滤器传递数值类型参数也不会出现异常。

5.模板继承

模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。

5.1父模板

如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。

标签block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。为了更好的可读性,建议给endblock标签协商名字,这个名字与对应的block名字相同。父模板中也可以使用上下文 中传递过来的数据。

{% block 名称 %} 
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock 名称 %}

5.2子模板

标签extends:继承,写在子模板文件的第一行

{% extends "父模板路径"%}

子模板不用填充父模板中所预留的区域,如果子模板没有填充,则使用父模板定义的默认值。

填充父模板中指定名称的预留区域。

{% block 名称 %} 
实际填充内容 
{{ block.super }}用于获取父模板中block的内容 
{% endblock 名称 %}

定义一个基本模型base.html

<!DOCTYPE html> 
<html lang="en"> 
<head>
	<meta charset="UTF-8"> 
	<title>{% block title %}{% endblock title %}</title> 
</head> 
<body> 
{% block header %} 
	<h1>顶部</h1> 
{% endblock header %}

{% block main %} 
	<h1>我是主要的部分</h1> 
{% endblock main %}

{% block footer %} 
	<h1>尾部</h1> 
{% endblock footer %} 
</body> 
</html>

定义一个详情页detail.html

{#把继承的模板写在最上面 #} 
{% extends 'base.html' %} 


{#需要改哪里直接实现 #} 
{% block title %} 
	详情页 
{% endblock title %} 


{% block main %} 
	<a href="#">点击我</a> 
{% endblock main %} 


{#不需要某个block直接重写 #} 
{% block footer %}{% endblock footer %}

模板渲染detail.html,输出结果
(如果忘记了回去看一下上一讲的内容哦!!!)

class IndexView2(View): 
	def get(self, request): 
	# 渲染模板,可以看到上面的两步,使用render一步就可以完成了 
	return render(request, "detail.html")

🚀总结

Django的模板到这里我们就全部讲完啦!!!!👍👍👍 如果有帮到你欢迎给个三连支持一下哦❤️ ❤️ ❤️
如果有哪些需要修改的地方欢迎指正啦!!!一起加油啦👏👏👏


文章标签:

原文连接:https://blog.csdn.net/weixin_53000329/article/details/124909696

相关推荐

Flask框架——消息闪现

34个图片压缩工具集合,包含在线压缩和CLI工具

入门即享受!coolbpf 硬核提升 BPF 开发效率 | 龙蜥技术

基于 OPLG 从 0 到 1 构建统一可观测平台实践

全链路灰度在数据库上我们是怎么做的?

冴羽答读者问:过程比结果重要吗?如果是,怎么理解?如果不是,又怎么解?

接口文档管理工具,选yapi 还是 Apifox? 这里列出了两款软件的深度分析,看完再下载不迟。

基于 Docker 来部署 Vue 或 React 前端项目及 Node 后端服务

三十岁的我,自由了!

如何实现带timeout的input?

统计千行代码Bug率,有没有意义?

814. 二叉树剪枝 : 简单递归运用题

【综合笔试题】难度 3.5\u002F5,多解法热门二叉树笔试题

为什么设计的软件不好用?那是因为不熟悉软件开发模型!一文熟悉软件开发模型

作为前端,我是这样从零实现CI\u002FCD二(node服务部署及前后端联调)

极智开发 | 讲解 Nginx 特性之一:反向代理

Netty 案例之 IM 方案设计

从 Google 离职,前Go 语言负责人跳槽小公司

最终一致性性分布式事务 TCC

不谈源码,聊聊位运算的实际应用