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

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

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

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

1.变量

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

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

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

{% endfor %}

2.注释

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

{ % endcomment % }

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

3.标签

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

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

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标签也支 持elif和else条件分支语句。
代码示例:
{% if ... %}
    ...

{% elif ... %}
    ...

{% else %}
    ...

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

{% endif %}

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

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

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

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

除上述功能性标签外,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",
中文系统分别输出"今天" "昨天" "明天"。

 ....

在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.过滤器

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

{{ 变量|过滤器方法 }}。过滤器可以连续使用,形式如:{{变量|过滤器方法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秒"

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

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

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

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

下面为过滤器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.模板继承

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

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

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

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

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

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

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

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

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

定义一个基本模型base.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):

    return render(request, "detail.html")

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

Original: https://blog.csdn.net/weixin_53000329/article/details/124909696
Author: 奋斗中的小贤
Title: 【python】Django系列08-Django中的模板(续)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/735633/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球