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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章