Django框架学习——4—(DTL模板标签、模版常用过滤器、模版结构优化、加载静态文件)

1、DTL模板标签

在for循环中,DTL提供了一些变量可供使用。

forloop.counter:     当前循环的下标。以1作为起始值。
forloop.counter0:    当前循环的下标。以0作为起始值。
forloop.revcounter:  当前循环的反向下标值。比如列表有5个元素,那么第一次遍历这个属性是等于5,第二次是4,以此类推。并且是以1作为最后一个元素的下标。
forloop.revcounter0: 类似于forloop.revcounter。不同的是最后一个元素的下标是从0开始。
forloop.first:       是否是第一次遍历。
forloop.last:        是否是最后一次遍历。
forloop.parentloop:  如果有多个循环嵌套,那么这个属性代表的是上一级的for循环。

for…in…empty标签:这个标签使用跟for…in…是一样的,只不过是在遍历的对象如果没有元素的情况下,会执行empty中的内容

{% for person in persons %}
    <li>{{ person }}</li>
{% empty %}
    暂时还没有任何人
{% endfor %}

注意:在for循环中,break,continue语句是用不了的。

1. url标签

url标签:在模版中,我们经常要写一些url,比如某个a标签中需要定义href属性。当然如果通过硬编码的方式直接将这个url写死在里面也是可以的。但是这样对于以后项目维护可能不是一件好事。因此建议使用这种反转的方式来实现,类似于django中的reverse一样。

<a href="{% url 'book:list' %}">图书列表页面</a>

如果url反转的时候需要传递参数,那么可以在后面传递。但是参数分位置参数和关键字参数。位置参数和关键字参数不能同时使用。

# path部分
path('detail/<book_id>/',views.book_detail,name='detail')


# url反转,使用位置参数
<a href="{% url 'book:detail' 1 %}">图书详情页面</a>

# url反转,使用关键字参数
<a href="{% url 'book:detail' book_id=1 %}">图书详情页面</a>

如果想要在使用url标签反转的时候要传递查询字符串的参数,那么必须要手动在在后面添加。

<!--  ?page=1是字符串拼接  -->
<a href="{% url 'book:detail' book_id=1 %}?page=1">图书详情页面</a>

如果需要传递多个参数,那么通过空格的方式进行分隔。

<!--  传递多个参数使用空格分离  -->
<a href="{% url 'book:detail' book_id=1 page=2 %}">图书详情页面</a>

with标签

<!--  with语句  -->
    {% with name=person.0 %}
        {{ name }}
    {% endwith %}

<!--  with语句  -->
    {% with person.0 as name %}
        {{ name }}
    {% endwith %}

autoescape 自动转义标签

视图文件:book/views.py,传递参数到前端页面进行渲染:

def book_detail(request):
    context = {
        "username": "12345",
        "book": ["python", "java", "php"],
        "books": ("python", "java", "php"),
        "info": {
            "name": "xxxxx",
            "url": "<a href='https://wwww.baidu.com'>百度</a>",            # 链接渲染到前端会因为源码中的render_to_string方法变成字符串
        },
        # 传递类
        "person": Person("ch")     
    }
    # 注意第一个参数request要有   # render在源码中封装了render_to_string和HttpResponse
    return render(request, "book_detail.html", context=context)

前端页面渲染book_detail.html:


    <!--info中的链接会自动转换成字符串,自动转义-->
    {{info.url}}
    <!--  处理后的链接可以正常显示,关闭自动转义, off关闭,on打开  -->
    {% autoescape off %}}
        {{info.url}}
    {% endautoescape %}}

更多标签 : https://docs.djangoproject.com/en/2.0/ref/templates/builtins/

创建新的Django项目:
在这里插入图片描述

2、模版常用过滤器

在模版中,有时候需要对一些数据进行处理以后才能使用。一般在Python中我们是通过函数的形式来完成的。而在模版中,则是通过过滤器来实现的。过滤器使用的是|来使用。

add

将传进来的参数添加到原来的值上面。这个过滤器会尝试将值和参数转换成整形然后进行相加。如果转换成整形过程中失败了,那么会将值和参数进行拼接。如果是字符串,那么会拼接成字符串,如果是列表,那么会拼接成一个列表。

{{ value|add:"2" }}

如果value是等于4,那么结果将是6。如果value是等于一个普通的字符串,比如abc,那么结果将是abc2。
实例如下:

from django.shortcuts import render
from django.template import defaultfilters


def index(request):
    context = {
        "num": 2,
        "str": 'abc',       
    }
    return render(request, 'index.html', context=context)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>测试</h1>
    <p>  首页</p>
    <!--  前端页面int类型加1操作  -->
    <p>{{ num|add:"1" }}</p>

    <!--  前端页面str类型加1操作  -->
    <p>{{ str|add:"1" }}</p>

    <!--  前端页面str类型加字符串操作  -->
    <p>{{ str|add:"xxxxx" }}</p>
</body>
</html>

在这里插入图片描述
列表相加相当于列表拼接。

cut

移除值中所有指定的字符串。类似于python中的replace(args,"")。

{{ value|cut:" " }}

前端页面渲染如下:
在这里插入图片描述

date

将一个日期按照指定的格式,格式化成字符串。

# 数据
context = {
    "birthday": datetime.now()
}
# 模版
{{ birthday|date:"Y/m/d" }}

在这里插入图片描述

 	<!--  date使用  -->
    <p>{{ birthday }}</p>
    <p>{{ birthday|date:"Y/m/d" }}</p>
    <p>{{ birthday|date:"Y/m/d H:i:s" }}</p>

在这里插入图片描述

default

如果值被评估为False。比如[],"",None,{}等这些在if判断中为False的值,都会使用default过滤器提供的默认值。

{{ value|default:"nothing" }}

如果value是等于一个空的字符串。比如"",那么以上代码将会输出nothing。

	<!-- default使用   -->
    <p>{{ info|default:"暂时没有设置签名" }}</p>

上面代码中info如果有值,会显示views.py中传输过来的值,如果没有,会显示default:“暂时没有设置签名”。

first

返回列表/元组/字符串中的第一个元素。

{{ value|first }}

last

返回列表/元组/字符串中的最后一个元素。

{{ value|last }}
def index(request):
    context = {
        "num": 2,
        "str": 'abc',
        "birthday": datetime.now(),
        "info": "个性签名",
        "l1": [1, 2, 3, 4, 5, 6, 7, 8],
        "z1": ("1", "2", "3", "4"),
    }
    return render(request, 'index.html', context=context)


index.html文件中渲染:
    <p>{{ l1|first }}</p>
    <p>{{ l1|last }}</p>
    <p>{{ z1|first }}</p>
    <p>{{ z1|last }}</p>

floatformat

使用四舍五入的方式格式化一个浮点类型。如果这个过滤器没有传递任何参数。那么只会在小数点后保留一个小数,如果小数后面全是0,那么只会保留整数。当然也可以传递一个参数,标识具体要保留几个小数。

<!--  ul标签是无序列表标签 ,显示结果为     34.3
                                        34.4
                                        34.353 -->
    <ul>
        <li>{{ 34.32|floatformat }}</li>
        <li>{{ 34.35|floatformat }}</li>
        <li>{{ 34.353333|floatformat:3}}</li>
    </ul>

join

类似与Python中的join,将列表/元组/字符串用指定的字符进行拼接.

{{ value|join:"/" }}

如果value是等于[‘a’,‘b’,‘c’],那么以上代码将输出a/b/c。

length

获取一个列表/元组/字符串/字典的长度。

{{ value|length }}

如果value是等于[‘a’,‘b’,‘c’],那么以上代码将输出3。如果value为None,那么以上将返回0。

lower

将值中所有的字符全部转换成小写。

{{ value|lower }}

upper

类似于lower,只不过是将指定的字符串全部转换成大写。

random

在被给的列表/字符串/元组中随机的选择一个值。

{{ value|random }}

safe

标记一个字符串是安全的。也即会关掉这个字符串的自动转义。

<!--  标记字符串是安全的,相当于关闭自动转义功能  -->
{{value|safe}}

如果value是一个不包含任何特殊字符的字符串,比如这种,那么以上代码就会把字符串正常的输入。如果value是一串html代码,那么以上代码将会把这个html代码渲染到浏览器中。

slice

类似于Python中的切片操作。

{{ some_list|slice:"2:" }}           从第2个元素到最后的元素

striptags

删除字符串中所有的html标签。

{{ value|striptags }}

truncatechars

如果给定的字符串长度超过了过滤器指定的长度。那么就会进行切割,并且会拼接三个点来作为省略号。

{{ value|truncatechars:5 }}

更多可以查看Django源码

from django.template import defaultfilters,defaulttags

3、模版结构优化

引入模版

有时候一些代码是在许多模版中都用到的。如果我们每次都重复的去拷贝代码那肯定不符合项目的规范。一般我们可以把这些重复性的代码抽取出来,就类似于Python中的函数一样,以后想要使用这些代码的时候,就通过include包含进来。这个标签就是include

# header.html
<p>我是header</p>

# footer.html
<p>我是footer</p>

# main.html
{% include 'header.html' %}
	<p>我是main内容</p>
{% include 'footer.html' %}

include标签寻找路径的方式。也是跟render渲染模板的函数是一样的。

默认include标签包含模版,会自动的使用主模版中的上下文,也即可以自动的使用主模版中的变量。如果想传入一些其他的参数,那么可以使用with语句

# header.html
<p>用户名:{{ username }}</p>

# main.html
{% include "header.html" with username='xxx' %}
<!--   with定义名称进行显示  -->

模板继承

在前端页面开发中。有些代码是需要重复使用的。这种情况可以使用include标签来实现。也可以使用另外一个比较强大的方式来实现,那就是模版继承。模版继承类似于Python中的类,在父类中可以先定义好一些变量和方法,然后在子类中实现。模版继承也可以在父模版中先定义好一些子模版需要用到的代码,然后子模版直接继承就可以了。并且因为子模版肯定有自己的不同代码,因此可以在父模版中定义一个block接口,然后子模版再去实现

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="{% static 'style.css' %}" />
    <title>{% block title %}
    			我的站点
    		{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
	        <ul>
	            <li><a href="/">首页</a></li>
	            <li><a href="/blog/">博客</a></li>
	        </ul>
        {% endblock %}
    </div>
    <div id="content">
        {% block content %}

		{% endblock %}
    </div>
</body>
</html>

这个是父模版,我们取名叫做base.html,定义好一个简单的html骨架,然后定义好两个block接口,让子模版来根据具体需求来实现。子模板然后通过extends标签来实现.

<!-- 继承父模板的信息  -->
{% extends "base.html" %}

{% block title %}
	博客列表
{% endblock %}

{% block content %}
    {% for entry in blog_entries %}
        <h2>{{ entry.title }}</h2>
        <p>{{ entry.body }}</p>
    {% endfor %}
{% endblock %}

模板继承注意点

  • extends标签必须放在模版的第一行。
  • 子模板中的代码必须放在block中,否则将不会被渲染。
  • 如果在某个block中需要使用父模版的内容,那么可以使用{{block.super}}来继承。比如上例,{%block title%},如果想要使用父模版的title,那么可以在子模版的title block中使用{{ block.super }}来实现。
  • 在定义block的时候,除了在block开始的地方定义这个block的名字,还可以在block结束的时候定义名字。比如{% block title %}{% endblock title %}。这在大型模版中显得尤其有用,能让你快速的看到block包含在哪里。
  • 子模板中的代码,如果没有放在{%block %}中,不会被渲染显示出来。

4、加载静态文件

在一个网页中,不仅仅只有一个html骨架,还需要css样式文件,js执行文件以及一些图片等。因此在DTL中加载静态文件是一个必须要解决的问题。在DTL中,使用static标签来加载静态文件。要使用static标签,首先需要{% load static %}

步骤如下:

  • 1.首先确保django.contrib.staticfiles已经添加到settings.INSTALLED_APPS中。(默认已经添加)
  • 2.确保在settings.py中设置了STATIC_URL。(默认创建了)
  • 3.在已经安装了的app下创建一个文件夹叫做static,然后再在这个static文件夹下创建一个当前app的名字的文件夹,再把静态文件放到这个文件夹下。

默认添加了django.contrib.staticfiles
在这里插入图片描述
默认创建了STATIC_URL
在这里插入图片描述
创建static文件夹:
在这里插入图片描述
注意:为什么在app下创建一个static文件夹,还需要在这个static下创建一个同app名字的文件夹呢?

原因是如果直接把静态文件放在static文件夹下,那么在模版加载静态文件的时候就是使用logo.jpg,如果在多个app之间有同名的静态文件,这时候可能就会产生混淆。而在static文件夹下加了一个同名app文件夹,在模版中加载的时候就是使用app/logo.jpg,这样就可以避免产生混淆

在这里插入图片描述
第四步如下:

  • 4.如果有一些静态文件是不和任何app挂钩的。那么可以在settings.py中添加STATICFILES_DIRS,以后DTL就会在这个列表的路径中查找静态文件。

settings.py

# 指定静态文件目录
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static")
]

在这里插入图片描述

  • 5.在模版中使用load标签加载static标签。比如要加载在项目的static文件夹下的style.css的文件。
 {% load static %}
 <link rel="stylesheet" href="{% static 'style.css' %}">
  • 6.如果不想每次在模版中加载静态文件都使用load加载static标签,那么可以在settings.py中的TEMPLATES/OPTIONS添加'builtins':['django.templatetags.static'],这样以后在模版中就可以直接使用static标签,而不用手动的load了。

settings.py:这样设置会在加载静态资源文件的路径前加上/static/路径


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],         # 模板路径设置
        'APP_DIRS': True,
        'OPTIONS': {
            # 不想每次在模版中加载静态文件都使用load加载static标签,以后在模版中就可以直接使用static标签,而不用手动的load了
            'builtins':['django.templatetags.static'],
            
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

这样在模版中就可以直接使用static标签,而不用手动的load了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!-- 加载静态资源文件中的css文件   -->
    <link rel="stylesheet" href="{% static 'index.css' %}">
</head>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章