您的当前位置:首页正文

第一章(四):Django框架的模板(DTL):变量、标签、模板过滤器、模板继承、配置模板文件(staticfiles)

2024-11-26 来源:个人技术集锦

系列文章目录





备注:欢迎查阅python之Django框架,如有疑问,欢迎评论,一定回复!!!


前言

提示:这里是本文要记录的大概内容:
Django的模板包含:动态部分、静态部分。动态部分即是Django的模板语言DTL,静态部分即是HTML、CSS、JavaScript。
模板语言主要是:模板变量、模板标签、模板过滤器。


提示:以下是本篇文章正文内容,如有疑问,欢迎评论中指出,定在一周内予以回复。

一 . 模板变量

模板变量可以被看作是HTML文件中的占位符。当Django模板引擎执行时,会用模板变量实际的值对其进行替换。

1.1 . 模板变量的类型

1.2 . 模板变量的应用:{{ 变量名 }}

注意:变量名前后都有空格,变量名可以由字母数字下划线组成,但不能包含空格和其它字符

1.2.1 . 变量使用实例

app中views.py的视图函数:

def var(request):
    '''
    变量的使用
    :param request:
    :return:
    '''
    lists = ['java', 'python', 'C', 'C#', 'JavaScript']
    dicts = {'姓名': "张三", "年龄": 25, "性别": '男'}
    return render(request, 'var.html', {'lists': lists, 'dicts': dicts})
    # return render(request, 'var.html', locals())

templates中,变量的引用:

<body>
    {{ lists }}
    <table border=1>
        <tr>
            <td>{{ lists.0 }}</td>
            <td>{{ lists.1 }}</td>
            <td>{{ lists.2 }}</td>
            <td>{{ lists.3 }}</td>
            <td>{{ lists.4 }}</td>
        </tr>
    </table>
<br>
    {{ dicts }}
    <table border=1>
        <tr>
            <td>{{ dicts.姓名 }}</td>
            <td>{{ dicts.年龄 }}</td>
            <td>{{ dicts.性别 }}</td>
        </tr>
    </table>
</body>

urls.py中,路由:

urlpatterns = [
    path('var/', views.var, name='app3_var'),
]

1.2.2 . 变量使用实例-效果释义

  • 1.2.1 中,视图函数中,render()所返回的数据的名称,一定是要和templates中{{ 变量名 }}一致;
  • 当变量是list/dict/对象时,引用其内部值:{{ list.索引 }}、{{ dict.keys }}
  • 访问路由,页面展示:

二 . 模板标签:{% 标签名 %}

模板标签的需要使用**标签限定符{% %}**进行包裹。
标签的作用:载入代码渲染模板,或者对传入的参数进行逻辑判断和计算。

2.1 . 常见标签

模板标签描述
{% if %}{% elif %}{% else%}{% endif %}条件判断模板标签
{% for %} {% empty %} {% endfor %}循环模板标签
{% url %}路由配置的地址标签
{% extends xx%}模板继承标签,从xx模板继承
{% load %}加载相关内容
{% static %}静态资源
{% block %}{% endblock %}一组占位符标签,需要重写模板
{% csrf_token %}用来防护跨站点伪造攻击
{% include 页面 %}包含一个HTML页面

2.2.1 . for循环标签的标签变量

变量描述
forloop.counter0表示当前循环的索引,从0开始计数
forloop.counter表示当前循环的索引,从1开始计数
forloop.revcounter0表示循环中剩余元素的数量,在进行第1次循环时 forloop.revcounter0的值是循环的序列中元素总数减去1,最后一次时,为0
forloop.revcounter表示循环中剩余元素的数量,在进行第1次循环时 forloop.revcounter的值是循环的序列中元素总数,最后一次时,为1
forloop.first表示是否是第1次循环
forloop.last表示是否是最后1次循环
forloop.parentloop嵌套循环中,获取上层的for循环

2.2.2 . 标签的使用:以for循环标签为例

扩展:
步骤一:在app3的views.py文件中,编写for_label函数

def for_label(request):
    '''
    标签的使用,以for循环为例
    :param request:
    :return:
    '''
    dict1 = {'书名': 'Django开发', '价格': 80, '作者': '张三'}
    dict2 = {'书名': 'Python开发', '价格': 100, '作者': '李四'}
    dict3 = {'书名': 'C#开发', '价格': 101, '作者': '王二'}
    list1 = [dict1, dict2, dict3]
    return render(request, 'for_label.html', {'lists': list1})

步骤二:在templates中,添加for_label.html,内容包含:

    <table border="1">
        {% for li in lists %}
            {% if forloop.first %}<!--如果是第一条记录-->
                <tr>
                <td>第一条记录:{{ li.书名 }}</td>
                </tr>
            {% endif %}
            <tr>
            <td>当前值:{{ li.书名 }},价格:{{ li.价格 }},当前正序索引{{ forloop.counter0 }},
                当前倒序索引{{ forloop.revcounter0 }}
            </td>
            </tr>
            {% if forloop.last %}<!--如果是最后一条记录-->
                <tr>
                <td>最后一个值:{{ li.书名 }}</td>
                </tr>
            {% endif %}
        {% endfor %}
    </table>

步骤三:在app3的路由url.py中,添加:

from django.urls import path, re_path
from app3 import views

urlpatterns = [
	……
    path('for_label/', views.for_label, name='app3_for_label'),
	……
]

2.2.3 . 2.2.2的效果释义

三 . 模板过滤器:{{ 变量名 | 过滤器:参数 }}

模板过滤器用于对模板变量进行操作。
使用格式:
{{ 变量名 | 过滤器:参数 }}

3.1 . 常用的模板过滤器

Django默认有60多个模板过滤器,下面仅列出常用的过滤器:


 - safe : {{name|safe}} : 关闭HTML标签和JavaScript脚本的语法标签的自动转义功能。
 - length : {{name|length}} : 获取模板变量的长度
 - default : {{name|default:"默认值"}} : 当变量的值为FALSE时,显示默认值
 - date : {{name|date:'Y-m-d G:i:s'}} : 格式化输出时间日期变量 
 - upper : {{name|upper}} : 把字符串转为大写
 - lower : {{name|lower}} : 把字符串转为小写
 - slice : {{name|slice:"2:4"}} : 以切片方式获取字符串的一部分,和python中的切片语法一样

3.1.1 . 以日期模板过滤器为例

  • Y表示年,格式为4位。y表示两位的年;
  • m表示月,格式为:01、02、12等;
  • d表示日,格式为:01、02等;
  • j表示日,格式为:1、2等;
  • H表示二十四进制的“时”,h表示十二进制的“时”;
  • i表示分,值为0~59;
  • s表示妙,值为0~59;
value|date:"Y年m月j日 H时i分s秒"

在app3/views.py中,添加函数:

import datetime

def filter_test(request):
    '''
    过滤器测试
    :param request:
    :return:
    '''
    str1 = "abcdefg"
    str2 = "ABCDEFG"
    slice_str = "1234567890"
    time_str = datetime.datetime.now()
    return render(request, "3_filter.html", {'str1': str1, 'str2': str2, "slice_str": slice_str, 'time_str': time_str})

在template/3_filter.html添加:

小写转大写:{{ str1|upper }}<br>
大写转小写:{{ str2|lower }}<br>
切片:{{ slice_str|slice:"2:4" }}<br>
日期:{{ time_str|date:"Y年m月j日 H时i分s秒 "}}<br>

在app3/url.py路由中,添加:

from django.urls import path, re_path
from app3 import views

urlpatterns = [
……
    path('for_filter/', views.filter_test, name='app3_for_filter'),
……
]

3.1.2 . 3.1.1效果释义

3.1.3 . 以safe模板过滤器为例

在app3/views.py中,添加函数:

def html_filler(request):
    '''
    safe过滤器  -- 关闭转义
    :param request:
    :return:
    '''
    html_addr = "<table border=1><tr><td>这是一个表格</td></tr></table>"
    html_script = "<script language='javascript'>document.write('非法执行');</script>"
    return render(request, 'html_filter.html', {'html_addr': html_addr, 'html_script': html_script})

在template/html_filter.html添加:

    关闭模板转义---表格:{{ html_addr|safe  }}<br>
    默认模板转义---表格:{{ html_addr }}<br>
    默认模板转义---脚本:{{ html_script }}<br>
    关闭模板转义---脚本:{{ html_script|safe }}<br>

在app3/url.py路由中,添加:

from django.urls import path, re_path
from app3 import views

urlpatterns = [
……
    path('html_filter/', views.html_filler, name='app3_html_filler'),
……
]

3.1.4 . 3.1.3效果释义

四 . 自定义过滤器

> 自定义过滤器,是Django模板过滤器的拓展。需要的准备工作:
> 1. 在app下 创建一个python包文件(package),命名:templatetags
> 2.在该templatetags包文件下,创建自定义标签,命名:myfilter.py
> `注意:这里的命名,影响在templates中html的装载{% load myfilter %}`

4.1 . 自定义过滤器-实例

from django import template

register = template.Library()


@register.filter
def show_title(value, n):
    if len(value) > n:
        return f'{value[0:n]}……'
    else:
        return value

注释:
自定义过滤器,需要使用装饰器filter;filter属于django下template包的Library的实例对象register
这个show_title过滤器函数的功能:当所过滤的字符串长度大于n时,显示……

  1. 在app3/views.py文件中,编写一个视图函数:
def diy_filter(request):
    dict1 = {'标题': '学习Python的好方法就是每天不间断的写代码'}
    dict2 = {'标题': '学习Django的好方法就是写一个CMS项目'}
    dict3 = {'标题': '学习新知识的好方法就是每天不间断的写代码'}
    dict4 = {'标题': '学习的意义'}
    li = [dict1, dict2, dict3, dict4]
    return render(request, 'diy_filter.html', {'lis': li})
  1. 在templates中创建一个diy_filter.html:
{#    先使用{% load 自定义标签 %}进行装载#}
    {% load myfilter %}
    <table border="1" style="width: 300px">
        {% for li in lis %}
            <tr><td>{{ li.标题 | show_title:10}}</td></tr>
        {% endfor %}
    </table>

功能释义:上面的模板文件diy_filter.html的主体内容,意思是show_title过滤器过滤的值长度超过10就显示……
4. 在urls.py中添加路由;然后,访问效果如下:

4.1.1 . 4.1 实例的效果

五 . 自定义标签

> 自定义标签可以分为两类: 简单标签( Simple Tags )和包含标签(Inclusion Tags)> `简单标签的实现与自定义过滤器类似。`需要的准备工作:
> 1. 在app下 创建一个python包文件(package),命名:templatetags
> 2.在该templatetags包文件下,创建自定义标签,命名:mytags.py
> `注意:这里的命名,影响在templates中html的装载{% load mytags %}`

5.1 . 简单标签:与 4.1 自定义过滤器类似

  1. 区别:标签函数的装饰器不同。@register.simple tag 是一个装饰器,指明 show title()函数是一个自定义的简单标签
from django import template

register = template.Library()


@register.simple_tag
def show_title(value, n):
    if len(value) > n:
        return f'{value[0:n]}……'
    else:
        return value
  1. 区别2: 在templates模板文件中,标签的使用不同。标签的使用{% 标签 参数1 参数2%}
{#    先使用{% load 自定义标签 %}进行装载#}
    {% load mytags %}
    <table border="1" style="width: 300px">
        {% for li in lis %}
            <tr><td>{% show_title li.标题 10 %}</td></tr>
        {% endfor %}
    </table>
  1. 效果和4.1一样,这里就不展示了。

5.2 . 包含标签

包含标签(Inclusion Tags)是指,通过染一些模板来展示数据的标签

5.2.1 . 包含标签-实例

  1. 在templatetags/mytags.py中,创建:
@register.inclusion_tag("show_info_tags.html")
def show_info_tags():
    dict1 = {'标题': '张三|2020-02-02'}
    dict2 = {'标题': '李四|2020-02-01'}
    dict3 = {'标题': '王五|2020-01-31'}
    lists = [dict1, dict2, dict3]
    return {'lists': lists}

其中,@register.inclusion tag 是一个装饰器,其参数用来渲染要显示的模板文件
2. 下面写要渲染的模板文件:show_info_tags.html。注意这个模板文件的名称和上面装饰器@register.inclusion_tag("show_info_tags.html")参数一致

<table border="1" style="width: 300px">
     {% for li in lists %}
         <tr><td>{{ li.标题 }}</td></tr>
     {% endfor %}
</table>
  1. 在views中,简单写一个视图函数。
def show_info(request):
    return render(request, 'show_info.html')
  1. 在templates中,创建一个模板文件:show_info.html
<body>
    {% load mytags %}
    <p>当前文件</p>
    <p>下面是加载模板文件show_info_tags.html</p>
    {% show_info_tags %}
</body>
  1. 写好urls.py路由后,访问。效果如下:

5.2.2 . 5.2.1包含标签实例的效果展示

六 . 模板继承:extends、include

模板继承就是建立一个基础的模板(也被称为“母版页”)。该母版页包含网站常见的元素,并且定义了一系列可以被内容页覆盖的“块” ( block )。

6.1 . 基础母版页所需:block 格子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        body,html{
            height: 100%;
            width: 100%;
        }
        .outer{display: flex;flex-direction: column;height: 100%}
        .middle{flex: 1;display: flex; background-color: white}
        .content{flex: 1; background: aliceblue;}
        .nav{
            display: flex;
            line-height: 40px;
            width: 100%;
            background-color: cadetblue;
            color: white;
            font-size: 24px;
            justify-content: center;
        }
        .left {
            width: 13%;
            background: cornflowerblue;
            overflow: auto;
            background-color: lightgrey;

        }
        .manage{
            display: flex;
            flex-direction: column;
            width:100%;
            height: 10%;
            background-color: lightseagreen;
            justify-content: center;
            align-items: center;
            margin-top: 10px;
            font-size:18px ;
            font-family: "Times New Roman";
        }
        a{
            text-decoration: none;
        }
        .manage:hover{
            background-color: darkcyan;
            font-size: 20px;

        }
        h1{
            text-align: center;
        }
    </style>
</head>
<body>
<div class="outer">
    <div class="nav">标题</div>
    <div class="middle">
        <div class="left">
            <div class="student manage"><a href="/app3/student/">学生管理</a></div>
            <div class="teacher manage"><a href="#">老师管理</a></div>
            <div class="course manage"><a href="#">课程管理</a></div>
            <div class="classes manage"><a href="#">课程管理</a></div>
        </div>
         <div class="content">
             {% block content %}
            <h1>WELCOME TO maoniuchuxing!!!</h1>
             {% endblock %}
        </div>
    </div>

</div>
</body>
</html>

6.2 . 继承基础页面的规则

  1. {%extends%}在模板中使用, 必须放在第一行 ,否则无效;
  2. 基础模板中的{%block%}标签越多越好,这样后面的继承就会更灵活;
  3. 不允许在同一个模板中定义多个同名的{% block %}

6.3 . include的使用

七 . 配置模板文件(staticfiles)

欢迎:评论、点赞、收藏!!!

显示全文