必備知識點 模版

Formerly0^0發表於2024-03-28

模版

1.尋找html模版

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                # 'django.contrib.auth.context_processors.auth',
                # 'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

優先去專案根目錄 > 每個已註冊的app的templates目錄找

2. 模版層渲染前端步驟

# 第一步 在檢視函式中 在render物件中新增一個引數 locals()
# locals() ---> 獲取到當前的名稱空間 

# 傳給了 render 函式中的第三個引數 context 引數 上下文物件

def register(request):
    # 【一】字串型別的資料
    name = "serein"

   
    return render(request, 'register.html', locals())

3. 前端渲染的八大基本資料型別

def index(request):
    # 字串型別
    n1 = "hello world"

    # 數字型別
    # 整型
    age = 19

    # 小數型別
    money = 100.98

    # 列表
    num = [1, 2, 3, 4]

    # 字典型別
    user_data = {"username": "serein", "password": "123", "age": 22, "hobby": ["music", "sport", "walk"],
                 "addr": {"country": "China", "location": "Shanghai"}}

    # 布林型別
    is_right = 2>3

    # 元組型別
    num_tuple = (1, 2, 3, 4, 5)

    # 【七】集合型別
    num_set = {1, 2, 3, 4, 5, 5, 5}
    return render(request, 'app01/index.html', locals())

前端頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#字串#}
<h1>index首頁{{ n1 }}</h1>
{#整數#}
<p>{{ age }}</p>
{#浮點數字#}
<p>{{ money }}</p>
<ul>
{#列表#}
    {% for i in num %}
    	<li>{{ i }}</li>
    {% endfor %}
</ul>
{#字典型別值,直接.獲取#}
<p>{{ user_data.addr.location }}</p>

{#布林型別#}
<p>{{ is_right }}</p>

{#元祖#}
<p>{{ num_tuple }}</p>

{#集合#}
<p>{{ num_set}}</p>

</body>
</html>


4.前端渲染函式和類

4.1 渲染函式

  • 渲染函式
  • 函式無返回值渲染結果是none
  • 函式有汗繪製渲染出來的是指定返回值
def function(request):
    # 無返回值
    def demo1():
        content = f"這是demo1函式"
        print(content)

    # 有返回值
    def demo2():
        content = f"這是demo2函式"
        return content

    return render(request, 'app01/demo.html', locals())

前端頁面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p>{{ demo1 }}</p>
<p>{{ demo2 }}</p>
</body>
</html>

4.2 渲染類

  • 渲染物件,就是相當於觸發了 Student 類的__str__ 方法
def cls_function(request):
    class Student:
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender

        # 繫結給物件的方法
        def read(self):
            print(f"{self.name} 正在看書")
            return f"這是繫結給物件的方法"

        # 繫結給類的方法
        @classmethod
        def wirte(cls):
            return f"這是繫結給類的方法"

        @staticmethod
        def sleep():
            return f"當前非繫結方法"

        def __str__(self):
            return f'這是 Student 類'

    student = Student('serein', 18, 'male')

    return render(request, 'app01/student.html', locals())

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#渲染物件,其實就是相當於觸發了 Student 類的__str__ 方法#}
{{ student }}

{#渲染物件屬性#}
{{ student.name }}

{#渲染物件的繫結方法和非繫結方法#}
{#繫結給物件的方法#}
{{ student.read }}
{#繫結給類的方法#}
{{ student.wirte }}
{#非繫結方法#}
{{ student.sleep }}
</body>

</html>

5.過濾器

5.1 過濾器簡介

在Django的模板語言中,透過使用 過濾器 來改變變數的顯示

5.2 語法

{{資料|過濾器:引數}}

注意事項:

  • 過濾器支援“鏈式”操作。即一個過濾器的輸出作為另一個過濾器的輸入。
  • 過濾器可以接受引數,例如:{{ sss|truncatewords:30 }},這將顯示sss的前30個詞。
  • 過濾器引數包含空格的話,必須用引號包裹起來。比如使用逗號和空格去連線一個列表中的元素,如:{{ list|join:', ' }}
  • |左右沒有空格!沒有空格!沒有空格!

5.3 常用過濾器

def demo3(request):
    name = 'serein'
    name1 = 'SEREIN'
    age = ''
    current_time = datetime.datetime.now()
    list1 = [1, 2, 3, 4, 5]
    html_content = "<p>蒹葭蒼蒼,白露為霜,所謂伊人,在水一方。</p>"
    # 第一種方法用mark_safe
    html_content = mark_safe(html_content)
    return render(request, 'app01/demo3.html', locals())

{% load jp %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{#計算變數長度#}
{{ name|length }}

{#變大寫#}
<p>{{ name|upper }}</p>

{#變小寫#}
<p>{{ name1|lower }}</p>

{#指定預設值#}
<p>{{ age|default:18 }}</p>

{#格式化日期物件#}
<p>{{ current_time|date:"Y-m-d H:i:s" }}</p>

{#切片,顧頭不顧尾#}
<p>{{ list1|slice:"0:2" }}</p>

{#切取摘要#}
<div>{{ list1|truncatechars:9 }}</div>

{#移除指定字元#}
<div>{{ name }}</div>
<div>{{ name|cut:"r" }}</div>

{#拼接,可以拼接的前提是後端的資料可以迭代#}
<div>{{ list1 }}</div>
<div>{{ list1|join:"|" }}</div>

{#取消轉義#}
{#<div>{{ html_content }}</div>#}
{#第二種方法#}
<div>{{ html_content|safe }}</div>

<h2>{{ name|myfunc }}</h2>
</body>
</html>

5.4 自定義過濾器方法模版

  • 使用template模組
  • 在app下建立temolatetags資料夾
  • 建立所需要自定義的方法的py檔案
  • 在前端頂部匯入

from django import template

register = template.Library()

# filter存在引數個數限制
@register.filter
def myfunc(value):
    return value.upper()
  
 
# simple_tag 不存在引數個數限制,返回文字
@register.simple_tag()
def mytag1():
    return "哈哈哈"


@register.simple_tag()
def mytag2(a1, a2):
    return a1 + a2
  
# inclusion_tag 不存在引數個數限制,返回html片段
@register.inclusion_tag("app01/xxxxx.html")
def xxx():
    return {"name": "serein", "age": 73}
{% load jp %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h2>{{ name|myfunc }}</h2>
  
<p>{% mytag1 %}</p>
<p>{% mytag2 'xxx' 'aaa' %}</p>
 
 # 返回的是inclusion_tag("app01/xxxxx.html")裡的內容
<p>{% xxx %}</p>
</body>
</html>

6. 標籤(tags)

6.1 for迴圈

6.1.1普通for迴圈
<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% endfor %}
</ul>
6.1.2 for迴圈可用的一些引數:
Variable Description
forloop.counter 當前迴圈的索引值(從1開始)
forloop.counter0 當前迴圈的索引值(從0開始)
forloop.revcounter 當前迴圈的倒序索引值(從1開始)
forloop.revcounter0 當前迴圈的倒序索引值(從0開始)
forloop.first 當前迴圈是不是第一次迴圈(布林值)
forloop.last 當前迴圈是不是最後一次迴圈(布林值)
forloop.parentloop 本層迴圈的外層迴圈
6.1.3 for ... empty

這是 Django 模板中的一段程式碼,用於在模板中遍歷一個使用者列表並顯示使用者的姓名。這段程式碼使用了模板中的 {% for %} 模板標籤和 {% empty %} 來處理列表為空的情況

具體而言,這段程式碼做了以下事情:

  • {% for user in user_list %}: 遍歷 user_list 列表中的每個使用者物件。
  • <li>{{ user.name }}</li>: 對於每個使用者,顯示一個列表項,其中包含使用者的姓名。
  • {% empty %}: 如果 user_list 為空,則執行這個塊中的內容。
  • <li>空空如也</li>: 在列表為空的情況下,顯示一個包含文字 "空空如也" 的列表項。

這樣,當 user_list 不為空時,會按照使用者列表中的順序顯示每個使用者的姓名;而當 user_list 為空時,會顯示一個包含 "空空如也" 的列表項

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% empty %}
    <li>空空如也</li>
{% endfor %}
</ul>

6.2 if判斷

6.2.1 if ~ elif ~ else
{% if user_list %}
  使用者人數:{{ user_list|length }}
{% elif black_list %}
  黑名單數:{{ black_list|length }}
{% else %}
  沒有使用者
{% endif %}
6.2.2 只有if和else
{% if user_list|length > 5 %}
  七座豪華SUV
{% else %}
    黃包車
{% endif %}

if語句支援 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。

6.3 with

  • 定義一箇中間變數,多用於給一個複雜的變數起別名。
  • 注意等號左右不要加空格。
{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}
{% with business.employees.count as total %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

6.4 csrf_token

  • 這個標籤用於跨站請求偽造保護。
  • 在頁面的form表單裡面寫上

6.5 註釋

{# ... #}

6.6 注意事項

  • Django的模板語言不支援連續判斷,即不支援以下寫法:
{% if a > b > c %}
...
{% endif %}
  • Django的模板語言中屬性的優先順序大於方法
def xx(request):
    d = {"a": 1, "b": 2, "c": 3, "items": "100"}
    return render(request, "xx.html", {"data": d})
  • 如上,我們在使用render方法渲染一個頁面的時候
    • 傳的字典d有一個key是items並且還有預設的 d.items() 方法
    • 此時在模板語言中:
{{ data.items }}
  • 預設會取d的items key的值。

6.7 forloop示例

d = ["你好", "我好", "大家好"]
{% for re in d %}

    <p>{{ forloop }}</p>

{% endfor %}
標籤
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 3, 'revcounter0': 2, 'first': True, 'last': False}

{'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}

{'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
  • first
    • 標識 for 迴圈是否是第一次
  • last
    • 標識 for 迴圈是否是以後一次
  • counter0
    • 類似索引
  • counter
    • 計數
  • 取值
d = ["你好", "我好", "大家好"]
{% for re in d %}

    <p>{{ re }}</p>

{% endfor %}
你好

我好

大家好

6.8 if語句示例

f = True
{% if f %}
    <p>你好</p>
{% else %}
    <p>我好</p>
{% endif %}
你好

6.9 混用 forloop + if 示例

d = ["你好", "我好", "大家好"]
{% for re in d %}
    {% if forloop.first %}
        <p>第一次迴圈</p>
    {% elif  forloop.last %}
        <p>最後一次迴圈</p>
    {% else %}
        <p>{{ re }}</p>
    {% endif %}
{% empty %}
    <p>for迴圈的物件是空,不支援for迴圈</p>

{% endfor %}
第一次迴圈

我好

最後一次迴圈

7. 模版的繼承

  • 某些頁面的整體大差不差,但是某一些區域性在做變化

7.1 模板

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Title</title>
  {% block page-css %}
  
  {% endblock %}
</head>
<body>

<h1>這是母板的標題</h1>

{% block page-main %}

{% endblock %}
<h1>母板底部內容</h1>
{% block page-js %}

{% endblock %}
</body>
</html>
  • 注意:我們通常會在母板中定義頁面專用的CSS塊和JS塊,方便子頁面替換。

7.2 繼承母板

  • 在子頁面中在頁面最上方使用下面的語法來繼承母板。
{% extends 'layouts.html' %}

7.3 塊(block)

  • 透過在母板中使用{% block xxx %}來定義"塊"。
  • 在子頁面中透過定義母板中的block名來對應替換母板中相應的內容。
{% block page-main %}
  <p>世情薄</p>
  <p>人情惡</p>
  <p>雨送黃昏花易落</p>
{% endblock %}

相關文章