Django模板層


一、模板介紹

Django的模板 = HTML代碼 + 模板語法

存放在templates目錄下的HTML文件就稱為模板文件,如果我們想要返回 的HTML文件中的數據是動態的,那么就必須在HTML文件中嵌入變量,這就會用到Django的模板語法。

二、變量

在Django的模板語言中的變量語法:

View:{ ' HTML變量名 ' : ‘ views變量名 ’ }

HTML:{{ 變量名 }}

views.py 文件

from django.shortcuts import render
import time


def index(request):
    times = time.time()
    name = '小楊'
    name_list = ['小楊', '艾倫', '鮑勃']
    info_dict = {'name': '小楊', 'age': 18, 'job': '攻城獅'}

    class A:
        def __init__(self, hobby):
            self.hobby = hobby

        def func(self):
            return self.hobby

    # 也可以傳入對象
    Bob = A('攻城獅')

    # 將數據傳遞給 index.html 文件進行渲染在發送給瀏覽器
    return render(request, 'index.html', {'times': times, 'Bob': Bob, 'name': name, 'name_list': name_list, 'info_dict': info_dict})

index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!-- 接收數據進行渲染 -->
<p>{{ times }}</p>
<p>{{ name }}</p>
<p>{{ name_list.2 }}</p>    <!-- 取列表中索引為2的數據 -->
<p>{{ info_dict.age }}</p>  <!-- 取字典中鍵值為age的數據 -->
<p>{{ Bob.func }}</p>       <!-- 執行對象中的方法返回數據 -->

</body>
</html>

三、過濾器

過濾器類似於python的內置函數,用來把視圖傳入的變量加以修飾后在顯示

過濾器的語法:{{ 變量名|過濾器 : 可選參數 }}

注意事項:

  1. 過濾器支持“ 鏈式 ” 操作 。
  2. 過濾器參數包含空格需要用引號包裹起來。
  3. '|' 左右沒有空格

常用過濾器

default

如果一個變量是false或者是空,就使用給定的默認值。否則,使用變量的值。

{{ value|default:"默認值" }}

length

返回值的長度,主要用於字符串和列表。

{{ value|length }}

filesizeformat

將值的格式轉換為一個可讀的,主要用於顯示文件大小

如果 value 是 123456789,輸出將會是 117.7 MB。

{{ value|filesizeformat }}

slice

切片

{{ value|slice:"2:4" }}

date

格式化,若value = datetime.datetime.now()

{{ value|date:"Y-m-d H:i:s" }}   

safe

轉義,若value是一串代碼,就可以對其進行轉義成非代碼的,防止xss攻擊。

{{ value|safe }}

truncatechars

如果字符串的字符個數多於指定的字符數量,那么就會被截斷。截斷的字符串將以可翻譯的序號(...)結尾

{{ value|truncatechars:'6' }}	# 后面的三個省略號也算在6個字符里面

truncatewords

在一定數量的字后截斷字符串,是截多少個單詞。

{{ value|truncatewords:2 }}

cut

移除value中所有的與給出的變量相同的字符串

{{ value|cut:'移除的字符' }}

join

使用字符串連接列表。

{{ list|join:', ' }}

四、標簽Tags

標簽是為了在模板中完成一些特殊功能,語法為{% 標簽名 %},一些標簽還需要搭配結束標簽 {% endtag %}

for 標簽

1、遍歷每一個元素

{% for food in foods_list %}
	<p>{{ food }}</p>
{% endfor %}

2、可以利用{% for obj in list reversed %}反向循環。

{% for food in foods_list reversed %}
	<p>{{ food }}</p>
{% endfor %}

3、遍歷一個字典

{% for k, v in f_dict.items %}
   <p>{{ k }}:{{ v }}</p>
{% endfor %}

for ... empty

可選的{ % empty % } 從句,給出的組是空的或者沒有被找到時,執行的操作

{% for food in foods_list %}
    <p>{{ food }}</p>

{% empty %}
    <p>沒有foods_list,或者foods_list為空</p>
{% endfor %}

for循環的其他方法

forloop.counter 		當前循環的索引值(從1開始),forloop是循環器,通過點來使用功能
forloop.counter0 		當前循環的索引值(從0開始)
forloop.revcounter 		當前循環的倒序索引值(從1開始)
forloop.revcounter0 	當前循環的倒序索引值(從0開始)
forloop.first 			當前循環是不是第一次循環(布爾值)
forloop.last 			當前循環是不是最后一次循環(布爾值)
forloop.parentloop 		本層循環的外層循環的對象,再通過上面的幾個屬性來顯示外層循環的計數等
forloop.parentloop.counter

if 標簽

對一個變量求值,如果它的值是“True” (存在,不為空,且不是boolean類型的False值),對應的內容塊會輸出。

if語句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷,注意條件兩邊都有空格。

{% if num > 100 or num < 0 %}
    <p>條件1滿足</p>  		<!--不滿足條件,不會生成這個標簽-->
{% elif num > 80 and num < 100 %}
    <p>條件1不滿足,條件2滿足</p>
{% else %}  		  <!--也是在if標簽結構里面的-->
    <p>條件都不成立,執行我吧</p>
{% endif %}

with 標簽

給一個復雜的變量起別名

{% with total=business.employees.count %}
    {{ total }} 	<!--只能在with語句體內用-->
{% endwith %}

或者

{% with business.employees.count as total %}
    {{ total }}
{% endwith %}

csrf_token 標簽

用於跨站請求偽造保護

在form表單里面任何位置寫上。

工作原理:

1、在GET請求到form表單時,標簽{% csrf_token%}會被渲染成一個隱藏的input標簽,該標簽包含了由服務端生成的一串隨機字符串,如下:

<input type="hidden" name="csrfmiddlewaretoken" value="dmFo...O5">

2、在使用form表單提交POST請求時,會提交上述隨機字符串,服務端在接收到該POST請求時會對比該隨機字符串,對比成功則處理該POST請求,否則拒絕,以此來確定客戶端的身份

實例:

<form action="" method="post">
    {% csrf_token %}
    用戶名:<input type="text">
    密碼:<input type="password">
    <input type="submit">
</form>

五、自定義過濾器和標簽

當內置的過濾器和標簽無法支持我們的需求時,就使用自定義標簽或過濾器

自定義過濾器

步驟:

1、在文件夾app01中創建子文件夾 templatetags (文件夾只能是templatetags)

2、在 templatetags 新建任意 .py 文件,如 mytags.py,在該文件中自定義過濾器或標簽。

內容如下

# mytags.py 文件
from django import template  # 導入的模塊

register = template.Library()  # register 固定的名字 注冊器


# 自定義過濾器

@register.filter
def my_filter1(v1):         # 不帶參數的
    # 對 v1 的操作
    v = v1 + '操作'
    return v
"""
使用:HTML文件中 
{% load 文件名 %}      --> 在HTML文檔中必須先加載存有自定義過濾器和標簽的文件
{{ value1|my_filter1 }}    --> 無參數
把 value1 的值傳入給 v1 ,做處理后返回。
"""


@register.filter
def my_filter2(v1, v2):     # 帶參數的過濾器(最多只能帶兩個)
    # 對 v1 v2 的操作
    v = v1 + v2
    return v
"""
使用:HTML文件中 
{% load 文件名 %}      --> 在HTML文檔中必須先加載存有自定義過濾器和標簽的文件
{{ value1|my_filter1:value2 }}    --> 有參數
把 value1 的值傳給 v1 ,參數 value2 傳給 v2 ,做處理后返回
"""

自定義標簽

步驟和自定義過濾器一樣:

# mytags.py 文件
from django import template  # 導入的模塊

register = template.Library()  # register 固定的名字 注冊器


@register.simple_tag
def my_tag(v1, v2, v3):     # 自定義的標簽可以定義多個參數
    # 對傳入的參數處理
    v = v1 + v2 + v3
    return v
"""使用:HTML文件中
{% load 文件名 %}      --> 在HTML文檔中必須先加載存有自定義過濾器和標簽的文件
{% my_tag value1 value2 value3 %}    
把 value1=v1 value2=v2 value3=v3 傳入標簽中,處理后返回。
"""

六、模板繼承

在Django模版引擎中最強大也是最復雜的部分就是模版繼承了。模版繼承可以讓您創建一個基本的 “骨架” 模版,它包含您站點中的全部元素,並且可以定義能夠被子模版覆蓋的 blocks 。

模板主要圍繞三種標簽的使用:include標簽、extends標簽、block標簽。

模板繼承之include標簽

include標簽也稱為組件

組件和插件的簡單區別:

  1. 組件是提供某一完整功能的模塊。
  2. 而插件更傾向於封閉某一功能方法的函數。

作用:在一個HTML模板文件中,引入或者重復使用另一個模板文件的內容。

{% include '模板名稱' %}

實例:

把整個 test.html 模板引入到 index.html 模板中

<!-- test.html 文件 -->
<div>
    <ul>
        <li>小楊</li>
        <li>小明</li>
        <li>鮑勃</li>
        <li>艾倫</li>
    </ul>
</div>


<!------------------------------------------------------------------------>
<!-- index.html 文件 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div>
{% include 'test.html' %} <!-- 此處,當此文件發送給客戶端的時候,就變成了test.html文件的內容了 -->
</div>

</body>
</html>

模板繼承之extends標簽、block標簽

作用:在一個HTML模板文件中,引入或者重復使用另一個模板文件的內容。

include 有的功能 extends 全都有,但是 extends 可以搭配一個block標簽,用於在繼承的基礎上增加新的內容

模板制定鈎子

{% block 鈎子名 %}
<!-- 另一HTML模板引入此模板時可以從此處填充自己的內容 -->
{% endblock 鈎子名 %}	

新模板引入舊模板,並從舊模板鈎子處填充新內容

{% extends '模板名' %}

<!-- 用新內容完全覆蓋了父模板鈎子中的內容 -->
{% block 鈎子名 %}
	<p> Hello World... </p>
{% endblock 鈎子名 %}

實例:

1、制定一個模板 base.html ,它定義了一個頁面上面的導航欄,和頁面左邊的菜單欄,網頁中間由我們引入模板時自行填充自己的內容。

|---------------------|
|		導航欄		    |
|-------|-------------|
|   菜  |			 |	
|	單  | 自行填充的內容 |
|	欄  |			 |
|-------|-------------|

模板 base.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .top {
            height: 100px;
            background-color: red;
        }
        .left {
            height: 400px;
            width: 20%;
            background-color: aqua;
            float: left;
        }
        .centre {
            float: right;
            height: 400px;
            width: 80%;
            background-color: green;
        }
    </style>

</head>
<body>

<div class="top">
    <a href="">導航一</a>
    <a href="">導航二</a>
    <a href="">導航三</a>
    <a href="">導航四</a>
</div>

<div class="counter">
    <div class="left">
        <p><a href="">菜單一</a></p>
        <p><a href="">菜單二</a></p>
        <p><a href="">菜單三</a></p>
        <p><a href="">菜單四</a></p>
    </div>

    <div class="centre">
    {% block centent %}
        <ul>
            <li>信息1</li>
            <li>信息2</li>
            <li>信息3</li>
        </ul>
        <!-- 另一HTML模板引入此模板時可以從此處填充自己的內容 -->

    {% endblock centent %}
    </div>
</div>

</body>
</html>

2、index.html 模板引入base.html 模板,並在 base.html 模板鈎子處添加新內容。

{% extends 'base.html' %}

{% block centent %}
{{ block.super }}	————> 該變量會將父模板中 centent 中原來的內容繼承過來


<!--在繼承父模板內容的基礎上新增的標簽-->
<form action="" method="post">
    {% csrf_token %}
    用戶名:<input type="text">
    密碼:<input type="password">
    <input type="submit">
</form>

{% endblock centent %}

3、當啟動 Django 訪問 index.html 頁面時返回的內容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .top {
            height: 100px;
            background-color: red;
        }
        .left {
            height: 400px;
            width: 20%;
            background-color: aqua;
            float: left;
        }
        .centre {
            float: right;
            height: 400px;
            width: 80%;
            background-color: green;
        }
    </style>

</head>
<body>

<div class="top">
    <a href="">導航一</a>
    <a href="">導航二</a>
    <a href="">導航三</a>
    <a href="">導航四</a>
</div>

<div class="counter">
    <div class="left">
        <p><a href="">菜單一</a></p>
        <p><a href="">菜單二</a></p>
        <p><a href="">菜單三</a></p>
        <p><a href="">菜單四</a></p>
    </div>

    <div class="centre">
    	<!-- 此處被替換 -->
        <form action="" method="post">
            <input type="hidden" name="csrfmiddlewaretoken" value="WE..DF">
            用戶名:<input type="text">
            密碼:<input type="password">
            <input type="submit">
        </form>
        
    </div>
</div>

</body>
</html>

總結:

  1. 標簽extends必須放在首行,base.html 中 block 越多控制性越強
  2. include 僅僅只是完全引用了其他模板文件,而 extends 卻可以搭配 block 在引用的基礎上進行擴寫
  3. 變量 {{ block.super }} 可以重用父類的內容,然后再父類基礎上增加新內容,而不是完全覆蓋
  4. 在一個模板中不能出現重名的block標簽。

七、靜態文件配置

在網站中我們需要用到大量的css、js、圖片等,這些都叫做靜態文件。

關於Django中靜態文件的配置,我們就需要在 settings 配置文件里面寫上這樣的內容:

1、例如在項目中創建一個 static_file 文件夾來存放靜態文件。

注意:別名可以隨便寫名字,但是如果改了名字,別忘了如果前端頁面如果是通過 /別名/靜態文件 調用靜態文件的話,前端頁面的靜態文件也要更改成一樣的

STATIC_URL = '/static/'		# 別名
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static_file')	
]

2、前端頁面引入靜態文件

方式一:不推薦,別名如果有變化,所有應用別名的地方都需要改

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/my.css">
</head>
<body>

<h1 class="c1" id="d1">點我就彈窗</h1>
<img src="/static/img/my.png" alt="">

<script src="/static/js/my.js"></script>

</body>
</html>

方式二:推薦,通過 load static 來找到別名,通過別名映射路徑的方式來獲取靜態文件

標簽static會接收傳入的參數,然后這根據settings.py中變量STATIC_URL的值拼接出一個完整的路徑

{% load static %}   <!-- 注意:必須先加載文件static.py -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 注意:此處的static是一個定義在 static.py 中的一個標簽,名字與文件名一樣 -->
    <link rel="stylesheet" href="{% static 'css/my.css' %}">
</head>
<body>

<h1 class="c1" id="d1">點我就彈窗</h1>
<img src="{% static 'img/my.png' %}" alt="">

<script src="{% static 'js/my.js' %}"></script>

</body>
</html>

方式三:get_static_prefix 標簽

和上面的效果一樣,不過只是用法不同。get_static_prefix 不能傳參,只能拼接,如下:

{% load static %}	<!-- 注意:必須先加載文件static.py -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% get_static_prefix %}css/my.css">
</head>
<body>

<h1 class="c1" id="d1">點我就彈窗</h1>
<img src="{% get_static_prefix %}img/my.png" alt="">

<script src="{% get_static_prefix %}js/my.js"></script>

</body>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM