第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Django 入門教程

課程導(dǎo)學(xué)
Django 慕課教程使用指南
Django開發(fā)實(shí)戰(zhàn)
35 開發(fā)實(shí)戰(zhàn)

Django 模板語言 DTL

接下來,我們會(huì)詳細(xì)描述 Django 內(nèi)置模板語言的語法 (DTL),和 Mako、Jinja2 一樣,需要掌握其注釋、變量、過濾器、標(biāo)簽、控制語句等等的寫法,并用實(shí)際的案例進(jìn)行說明。

1. DTL 基礎(chǔ)用法

1.1 變量

DTL 中變量的寫法為 {{ variable }}, 這和 Jinja2 非常類似。模版引擎碰到模板變量時(shí),會(huì)從上下文 context 中獲取這個(gè)變量的值,然后用該值替換掉它本身。變量的命名包括任何字母數(shù)字以及下劃線("_")的組合,其中點(diǎn)(".")號(hào)在 DTL 中是有特殊含義的,因此要注意:變量名稱中不能有空格或標(biāo)點(diǎn)符號(hào)。

<p>{{ content }}</p>
<div>{{ spyinx.age }}</div>

注意:spyinx.age 表示的是 spyinx 的 age 屬性值。我們可以基于 manager.py 的 shell 命令做如下測試:

(django-manual) [root@server first_django_app]# cat templates/test1.html 
<p>{{ content }}</p>
<div>{{ spyinx.age }}</div>

(django-manual) [root@server first_django_app]# python manage.py shell
Python 3.8.1 (default, Dec 24 2019, 17:04:00) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.template.loader import get_template
>>> tp = get_template('test1.html')
>>> tp.render(context={'content': '正文我文本', 'spyinx': {'age': 29, 'sex': 'male'}})
'<p>正文我文本</p>\n<div>29</div>\n'
>>> text = tp.render(context={'content': '正文我文本', 'spyinx': {'age': 29, 'sex': 'male'}})
>>> print(text)
<p>正文我文本</p>
<div>29</div>

1.2 標(biāo)簽

DTL 中標(biāo)簽的寫法為: {% 標(biāo)簽 %},常用的標(biāo)簽有 for 循環(huán)標(biāo)簽,條件判斷標(biāo)簽 if/elif/else。部分標(biāo)簽在使用時(shí),需要匹配對(duì)應(yīng)的結(jié)束標(biāo)簽。Django 中常用的內(nèi)置標(biāo)簽如下表格所示:

標(biāo)簽 描述
{% for %} for 循環(huán),遍歷變量中的內(nèi)容
{% if %} if 判斷
{% csrf_token %} 生成 csrf_token 的標(biāo)簽
{% static %} 讀取靜態(tài)資源內(nèi)容
{% with %} 多用于給一個(gè)復(fù)雜的變量起別名
{% url %} 反向生成相應(yīng)的 URL 地址
{% include 模板名稱 %} 加載指定的模板并以標(biāo)簽內(nèi)的參數(shù)渲染
{% extends 模板名稱 %} 模板繼承,用于標(biāo)記當(dāng)前模板繼承自哪個(gè)父模板
{% block %} 用于定義一個(gè)模板塊

1.2.1 for 標(biāo)簽的用法

{# 遍歷列表 #}
<ul>
{% for person in persons %}
<li>{{ person }}</li>
{% endfor %}
</ul>

{# 遍歷字典 #}
<ul>
{% for key, value in data.items %}
<li>{{ key }}:{{ value }}</li>
{% endfor %}
</ul>

在 for 循環(huán)標(biāo)簽中,還提供了一些變量,供我們使用:

變量 描述
forloop.counter 當(dāng)前循環(huán)位置,從1開始
forloop.counter0 當(dāng)前循環(huán)位置,從0開始
forloop.revcounter 反向循環(huán)位置,從n開始,到1結(jié)束
forloop.revcounter0 反向循環(huán)位置,從n-1開始,到0結(jié)束
forloop.first 如果是當(dāng)前循環(huán)的第一位,返回True
forloop.last 如果是當(dāng)前循環(huán)的最后一位,返回True
forloop.parentloop 在嵌套for循環(huán)中,獲取上層for循環(huán)的forloop

實(shí)驗(yàn)

(django-manual) [root@server first_django_app]# cat templates/test_for.html 
遍歷列表:
<ul>
{% spaceless %}
{% for person in persons %}
{% if forloop.first %}
<li>第一次:{{ forloop.counter }}:{{ forloop.counter0 }}:{{ person }}:{{ forloop.revcounter }}:{{ forloop.revcounter }}</li>
{% elif forloop.last %}
<li>最后一次:{{ forloop.counter }}:{{ forloop.counter0 }}:{{ person }}:{{ forloop.revcounter }}:{{ forloop.revcounter }}</li>
{% else %}
</li>{{ forloop.counter }}:{{ forloop.counter0 }}:{{ person }}:{{ forloop.revcounter }}:{{ forloop.revcounter }}</li>
{% endif %}
{% endfor %}
{% endspaceless %}
</ul>

{% for name in name_list %} 
{{ name }}
{% empty %} 
<p>name_list變量為空</p>
{% endfor %} 

倒序遍歷列:
{% spaceless %}
{% for person in persons reversed %}
<p>{{ person }}:{{ forloop.revcounter }}</p>
{% endfor %}
{% endspaceless %}

遍歷字典:
{% spaceless %}
{% for key, value in data.items %}
<p>{{ key }}:{{ value }}</p>
{% endfor %}
{% endspaceless %}


(django-manual) [root@server first_django_app]# python manage.py shell
Python 3.8.1 (default, Dec 24 2019, 17:04:00) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.template.loader import get_template
>>> tp = get_template('test_for.html')
>>> content = tp.render(context={'persons':['張三', '李四', '王二麻子'], 'name_list': [], 'data': {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}})
>>> print(content)
遍歷列表:
<ul>
<li>第一次:1:0:張三:3:3</li></li>2:1:李四:2:2</li><li>最后一次:3:2:王二麻子:1:1</li>
</ul>

 
<p>name_list變量為空</p>
 

倒序遍歷列:
<p>王二麻子:3</p><p>李四:2</p><p>張三:1</p>

遍歷字典:
<p>key1:value1</p><p>key2:value2</p><p>key3:value3</p>

1.2.2 if 標(biāo)簽

支持嵌套,判斷的條件符號(hào)與變量之間必須使用空格隔開,示例如下。

(django-manual) [root@server first_django_app]# cat templates/test_if.html
{% if spyinx.sex == 'male' %}
<label>他是個(gè)男孩子</label>
{% else %}
<label>她是個(gè)女孩子</label>
{% endif %}
(django-manual) [root@server first_django_app]# python manage.py shell
Python 3.8.1 (default, Dec 24 2019, 17:04:00) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.template.loader import get_template
>>> tp = get_template('test_if.html')
>>> tp.render(context={'spyinx': {'age':29, 'sex': 'male'}})
'\n<label>他是個(gè)男孩子</label>\n\n'
>>> tp.render(context={'spyinx': {'age':29, 'sex': 'male'}})

1.2.3 csrf_token 標(biāo)簽

這個(gè)標(biāo)簽會(huì)生成一個(gè)隱藏的 input 標(biāo)簽,其值為一串隨機(jī)的字符串。這個(gè)標(biāo)簽通常用在頁面上的 form 標(biāo)簽中。在渲染模塊時(shí),使用 RequestContext,由它處理 csrf_token 這個(gè)標(biāo)簽。下面來做個(gè)簡單的測試:

# 模板文件
[root@server first_django_app]# cat templates/test_csrf.html 
<html>
<head></head>
<body>
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
<div><span>賬號(hào):</span><input type="text" style="margin-bottom: 10px" placeholder="請(qǐng)輸入登錄手機(jī)號(hào)/郵箱" /></div>
<div><span>密碼:</span><input type="password" style="margin-bottom: 10px" placeholder="請(qǐng)輸入密碼" /></div>
<div><label style="font-size: 10px; color: grey"><input type="checkbox" checked="checked"/>7天自動(dòng)登錄</label></div>
<div style="margin-top: 10px"><input type="submit"/></div>
</form>
</body>
</html>

# 定義視圖:hello_app/views.py
[root@server first_django_app]# cat hello_app/views.py 
from django.shortcuts import render

# Create your views here.
def test_csrf_view(request, *args, **kwargs):
    return render(request, 'test_csrf.html', context={})

# 配置URLconf:hello_app/urls.py
[root@server first_django_app]# cat hello_app/urls.py
from django.urls import path

urlpatterns = [
    path('test-csrf/', views.test_csrf_view),
]

# 最后激活虛擬環(huán)境并啟動(dòng)django工程
[root@server first_django_app] pyenv activate django-manual
(django-manual) [root@server first_django_app]# python manage.py runserver 0:8881
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

March 27, 2020 - 04:10:05
Django version 2.2.11, using settings 'first_django_app.settings'
Starting development server at http://0:8881/
Quit the server with CONTROL-C.

現(xiàn)在通過外部請(qǐng)求這個(gè)URL,效果圖如下。通過右鍵的檢查功能,可以看到 {% csrf_token %} 被替換成了隱藏的 input 標(biāo)簽,value 屬性是一個(gè)隨機(jī)的長字符串:

圖片描述

csrf_token標(biāo)簽

1.2.4 with 標(biāo)簽

對(duì)某個(gè)變量重新命名并使用:

(django-manual) [root@server first_django_app]# cat templates/test_with.html 
{% spaceless %}
{% with age1=spyinx.age %}
<p>{{ age1 }}</p>
{% endwith %}
{% endspaceless %}

{% spaceless %}
{% with spyinx.age as age2 %}
<div>{{ age2 }} </div>
{% endwith %}
{% endspaceless %}

(django-manual) [root@server first_django_app]# python manage.py shell
Python 3.8.1 (default, Dec 24 2019, 17:04:00) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.template.loader import get_template
>>> tp = get_template('test_with.html')
>>> content = tp.render(context={'spyinx': {'age': 29}})
>>> print(content)
<p>29</p>

<div>29 </div>

1.2.5 spaceless 標(biāo)簽

移除 HTML 標(biāo)簽中的空白字符,包括空格、tab鍵、換行等。具體示例參見上面的示例;

1.2.6 cycle 標(biāo)簽

循環(huán)提取 cycle 中的值,用法示例如下

# 假設(shè)模板如下:
{% for l in list %}
<tr class="{% cycle 'r1' 'r2' 'r3'%}">
{{l}}
</tr>
{% endfor %}

# 對(duì)于傳入的 list 參數(shù)為:['l1', 'l2', 'l3'],最后生成的結(jié)果如下:
<tr class="r1">
l1
</tr>

<tr class="r2">
l2
</tr>

<tr class="r3">
l3
</tr>

1.2.7 include 標(biāo)簽

加載其他模板進(jìn)來。

{% include "base/base.html" %}

除了加載模板進(jìn)來外,include 標(biāo)簽還可以像加載進(jìn)來的模板傳遞變量。假設(shè)我們有個(gè) base/base.html 模板文件,其內(nèi)容為:

{# base/base.html #}
Hello {{ name|default:"Unknown" }}

此時(shí),我們引入 base.html 模板文件時(shí),可以給 name 傳遞變量值:

{% include "base/base.html" with name="test"  %}

1.3 注釋

在 DTL 中單行注釋使用 {# 單行注釋內(nèi)容 #} 這樣的方式,對(duì)于多行注釋,我們使用 comment 標(biāo)簽:

{# 單行注釋內(nèi)容 #}

{% comment %}
多行注釋內(nèi)容
{% endcomment %}

1.4 過濾器

DTL 中的過濾器會(huì)在下一節(jié)中詳細(xì)介紹。

2. DTL 中的模板繼承

在這里將介紹 DTL 中的模板繼承語法,主要涉及到 block、extends 兩個(gè)標(biāo)簽。Django 中的模板和 Python 中的類一樣是可以被繼承的,通過合理的模板繼承可以減少前端的工作量,提高代碼的復(fù)用性以及開發(fā)效率。例如下面的 w3school 的在線教程網(wǎng)站:

圖片描述

w3school在線教程首頁

大致上,該網(wǎng)站有一個(gè)固定的頭部,有一些側(cè)邊欄,以及內(nèi)容主體部分?,F(xiàn)在我們使用 Django 中的模板教程來完成一個(gè)這樣的簡單例子。

首先在 template 目錄下準(zhǔn)備網(wǎng)站的框架模板文件 base.html,其內(nèi)容如下:

<html>
{% load staticfiles %}
<head>
</head>

<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<body>

<!-- 大容器 -->
<div class="container">
	<div class="header"><center>網(wǎng)站頭部</center></div>
	<div class="sidebar">
                {% block sidebar %} {% endblock %}
	</div>
	<div class="content">
		{% block content %} {% endblock %}
	</div>
</div>

</body>
</html>

由于模板文件中加載了靜態(tài)資源文件,我們除了加上靜態(tài)資源文件外,還需要加上在 Django 的全局配置文件中進(jìn)行相關(guān)屬性的設(shè)置:

新建 static 目錄,并在其下新建 css 目錄,然后準(zhǔn)備樣式表 main.css:

.container {
	border-style: dotted;
	border-color: red;
	border-width: 10px;
	width: 90%;
	height: 80%;
}

.container .header {
    border-bottom-style: solid;
    border-color: black;
	border-width: 5px;
	font-size: 24px;
	height: 100px;
    line-height: 100px;
}

.container .sidebar {
	border-right-style: solid;
    border-color: black;
	border-width: 5px;
	font-size: 24px;
	width: 20%;
	float: left;
    height: 80%;
}

.container .content {
    float: left;
    width: 60%;
}

.container .content .title {
	margin-top: 20px;
    margin-left: 40%;
    width: 100%;
    font-size: 24px;
    font-weight: bold;
}

在 Django 的 settings.py 文件中添加 STATICFILES_DIRS 屬性:

STATIC_URL = '/static/'
# 新添加的配置,方便前面的模板文件中找到靜態(tài)資源路徑
STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static") ]

可以看到,在前面的 base.html 文件中,我們定義了頁面的基本框架,包括了網(wǎng)站頭部、側(cè)邊欄數(shù)據(jù)以及內(nèi)容主體。其中側(cè)邊欄和內(nèi)容主體部分分別定義了兩個(gè) block 標(biāo)簽,并進(jìn)行了命名。接下來我們新建模板文件 test_extends.html,該模板文件繼承自 base.html,并給出兩個(gè) block 標(biāo)簽對(duì)應(yīng)的數(shù)據(jù):

{# 繼承base.html模板文件 #}
{% extends "base.html" %}

{# 側(cè)邊欄 #}
{% block sidebar %}
<ul>
    {% for lesson in lessons %}
    <li><a href="{{ lesson.addr }}">{{ lesson.name }}</a></li>
    {% endfor %}
</ul>
{% endblock %}

{# 內(nèi)容主體 #}
{% block content %}
<div class="title">{{ title }}</div>
{% endblock %}

準(zhǔn)備好視圖函數(shù),這里我們會(huì)實(shí)現(xiàn)兩個(gè)視圖,使用的模板是一樣的,但是填充的數(shù)據(jù)不一樣而已:

# hello_app/views.py
from django.shortcuts import render

def test_django_view(request, *args, **kwargs):
    data = {
       'title': 'Django教程手冊',
       'lessons': [
          {'name': 'web框架', 'addr': '/web_framework'},
          {'name': 'django發(fā)展歷史', 'addr': '/django_history'},
          {'name': 'django基礎(chǔ)上', 'addr': '/base_one'},
          {'name': 'django基礎(chǔ)下', 'addr': '/base_two'},
          
       ]
    }
    return render(request, 'test_extends.html', context=data)

def test_nginx_view(request, *args, **kwargs):
    data = {
       'title': 'Nginx教程手冊',
       'lessons': [
          {'name': 'Nginx介紹', 'addr': '/web_server'},
          {'name': 'Nginx發(fā)展歷史', 'addr': '/nginx_history'},
          {'name': 'Nginx優(yōu)勢', 'addr': '/nginx_advantages'},

       ]
    }
    return render(request, 'test_extends.html', context=data)

準(zhǔn)備好 URLconf 配置:

from django.urls import path, re_path

urlpatterns = [
    path('test-django/', views.test_django_view),
    path('test-nginx/', views.test_nginx_view),
]

啟動(dòng) Django 服務(wù)頁面,然后分別請(qǐng)求/hello/test-django//hello/test-nginx/ 兩個(gè)地址,可以看到如下兩個(gè)效果圖,網(wǎng)頁的整體布局不變,但是數(shù)據(jù)不同。幾乎所有的大型網(wǎng)站都是靠這樣繼承模式實(shí)現(xiàn)的優(yōu)化前端代碼和統(tǒng)一頁面的風(fēng)格。

圖片描述

test-django效果圖

圖片描述

test-nginx效果圖

通過上面的簡單實(shí)驗(yàn),我們能夠理解并初步掌握 Django 中模板的繼承用法。這種基于繼承網(wǎng)頁的做法能使得我們開發(fā)的網(wǎng)站具有統(tǒng)一的風(fēng)格,也是后面經(jīng)常會(huì)用到的一種模板編寫手段。

3. 小結(jié)

本小節(jié)我們詳細(xì)介紹了 Django 中自帶的模板引擎的語法,介紹了各種 DTL 的標(biāo)簽以及其用法并進(jìn)行了測試。此外還通過一個(gè)簡單的實(shí)戰(zhàn)例子介紹了 DTL 中的模板繼承語法。這些是后面編寫 HTML 模板的基礎(chǔ),必須熟練掌握。接下來會(huì)繼續(xù)介紹 DTL 中的過濾器以及如何自定義過濾器。