<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在上一章節中我們使用 django.http.HttpResponse() 來輸出 "Hello World!"。該方式將資料與檢視混合在一起,不符合 Django 的 MVC 思想。
本章節我們將為大家詳細介紹 Django 模板的應用,模板是一個文字,用於分離檔案的表現形式和內容。
我們接著上一章節的專案將在 HelloWorld 目錄底下建立 templates 目錄並建立 runoob.html檔案,整個目錄結構如下:
HelloWorld/ |-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- settings.py | |-- settings.pyc | |-- urls.py | |-- urls.pyc | |-- views.py | |-- views.pyc | |-- wsgi.py | `-- wsgi.pyc |-- manage.py `-- templates `-- runoob.html
runoob.html 檔案程式碼如下:
<h1>{{ hello }}</h1>
從模板中我們知道變數使用了雙括號。
接下來我們需要向Django說明模板檔案的路徑,修改HelloWorld/settings.py,修改 TEMPLATES 中的 DIRS 為 [BASE_DIR+"/templates",],如下所示:
...TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [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', ], }, }, ] ...
我們現在修改 views.py,增加一個新的物件,用於向模板提交資料:
from django.shortcuts import render def runoob(request): context = {} context['hello'] = 'Hello World!' return render(request, 'runoob.html', context)
urls.py 檔案程式碼:
from django.urls import path from . import views urlpatterns = [ path('runoob/', views.runoob), ]
可以看到,我們這裡使用 render 來替代之前使用的 HttpResponse。render 還使用了一個字典 context 作為引數。
context 字典中元素的鍵值 hello 對應了模板中的變數 {{ hello }}。
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
這樣我們就完成了使用模板來輸出資料,從而實現資料與檢視分離。
接下來我們將具體介紹模板中常用的語法規則。
模板語法:
view:{"HTML變數名" : "views變數名"} HTML:{{變數名}}
from django.shortcuts import render def runoob(request): views_name = "菜鳥教學" return render(request,"runoob.html", {"name":views_name})
templates 中的 runoob.html :
<p>{{ name }}</p>
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
templates 中的 runoob.html中,可以用 . 索引下標取出對應的元素。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_list = ["菜鳥教學1","菜鳥教學2","菜鳥教學3"] return render(request, "runoob.html", {"views_list": views_list})
HelloWorld/templates/runoob.html 檔案程式碼:
<p>{{ views_list }}</p> # 取出整個列表 <p>{{ views_list.0 }}</p> # 取出列表的第一個元素
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
templates 中的 runoob.html中,可以用 .鍵 取出對應的值。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_dict = {"name":"菜鳥教學"} return render(request, "runoob.html", {"views_dict": views_dict})
HelloWorld/templates/runoob.html 檔案程式碼:
<p>{{ views_dict }}</p> <p>{{ views_dict.name }}</p>
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
模板語法:
{{ 變數名 | 過濾器:可選引數 }}
模板過濾器可以在變數被顯示前修改它,過濾器使用管道字元,如下所示:
{{ name|lower }}
{{ name }} 變數被過濾器 lower 處理後,檔案大寫轉換文字為小寫。
過濾管道可以被* 套接* ,既是說,一個過濾器管道的輸出又可以作為下一個管道的輸入:
{{ my_list|first|upper }}
以上範例將第一個元素並將其轉化為大寫。
有些過濾器有引數。 過濾器的引數跟隨冒號之後並且總是以雙引號包含。 例如:
{{ bio|truncatewords:"30" }}
這個將顯示變數 bio 的前30個詞。
其他過濾器:
{{ pub_date|date:"F j, Y" }}
(1)default
default 為變數提供一個預設值。
如果 views 傳的變數的布林值是 false,則使用指定的預設值。
以下值為 false:
0 0.0 False 0j "" [] () set() {} None
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): name =0 return render(request, "runoob.html", {"name": name})
HelloWorld/templates/runoob.html 檔案程式碼:
{{ name|default:"菜鳥教學666" }}
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
(2)length
返回物件的長度,適用於字串和列表。
字典返回的是鍵值對的數量,集合返回的是去重後的長度。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): name ="菜鳥教學" return render(request, "runoob.html", {"name": name})
HelloWorld/templates/runoob.html 檔案程式碼:
{{ name|length}}
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
(3)filesizeformat
以更易讀的方式顯示檔案的大小(即'13 KB', '4.1 MB', '102 bytes'等)。
字典返回的是鍵值對的數量,集合返回的是去重後的長度。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): num=1024 return render(request, "runoob.html", {"num": num})
HelloWorld/templates/runoob.html 檔案程式碼:
{{ num|filesizeformat}}
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
(4)date
根據給定格式對一個日期變數進行格式化。
格式 Y-m-d H:i:s返回 年-月-日 小時:分鐘:秒 的格式時間。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): import datetime now =datetime.datetime.now() return render(request, "runoob.html", {"time": now})
HelloWorld/templates/runoob.html 檔案程式碼:
{{ time|date:"Y-m-d" }}
再次存取 http://127.0.0.1:8000/runoob,可以看到頁面:
(5)truncatechars
如果字串包含的字元總個數多於指定的字元數量,那麼會被截斷掉後面的部分。
截斷的字串將以 ... 結尾。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_str = "菜鳥教學" return render(request, "runoob.html", {"views_str": views_str})
HelloWorld/templates/runoob.html 檔案程式碼:
{{ views_str|truncatechars:2}}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
(6)safe
將字串標記為安全,不需要跳脫。
要保證 views.py 傳過來的資料絕對安全,才能用 safe。
和後端 views.py 的 mark_safe 效果相同。
Django 會自動對 views.py 傳到HTML檔案中的標籤語法進行跳脫,令其語意失效。加 safe 過濾器是告訴 Django 該資料是安全的,不必對其進行跳脫,可以讓該資料語意生效。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_str = "<a href='https://www.runoob.com/'>點選跳轉</a>" return render(request, "runoob.html", {"views_str": views_str})
HelloWorld/templates/runoob.html 檔案程式碼:
{{ views_str|safe }}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
基本語法格式如下:
{% if condition %} ... display {% endif %}
或者:
{% if condition1 %} ... display 1 {% elif condition2 %} ... display 2 {% else %} ... display 3 {% endif %}
根據條件判斷是否輸出。if/else 支援巢狀。
{% if %} 標籤接受 and , or 或者 not 關鍵字來對多個變數做判斷 ,或者對變數取反( not ),例如:
{% if athlete_list and coach_list %} athletes 和 coaches 變數都是可用的。 {% endif %}
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_num = 88 return render(request, "runoob.html", {"num": views_num})
HelloWorld/templates/runoob.html 檔案程式碼:
{%if num > 90 and num <= 100 %} 優秀 {% elif num > 60 and num <= 90 %} 合格 {% else %} 一邊玩去~ {% endif %}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
{% for %} 允許我們在一個序列上迭代。
與 Python 的 for 語句的情形類似,迴圈語法是 for X in Y ,Y 是要迭代的序列而 X 是在每一個特定的迴圈中使用的變數名稱。
每一次迴圈中,模板系統會渲染在 {% for %} 和 {% endfor %} 之間的所有內容。
例如,給定一個運動員列表 athlete_list 變數,我們可以使用下面的程式碼來顯示這個列表:
<ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul>
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_list = ["菜鳥教學","菜鳥教學1","菜鳥教學2","菜鳥教學3",] return render(request, "runoob.html", {"views_list": views_list})
HelloWorld/templates/runoob.html 檔案程式碼:
{% for i in views_list %} {{ i }} {% endfor %}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
給標籤增加一個 reversed 使得該列表被反向迭代:
{% for athlete in athlete_list reversed %} ... {% endfor %}
HelloWorld/templates/runoob.html 檔案程式碼:
{% for i in views_list reversed%} {{ i }} {% endfor %}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
遍歷字典: 可以直接用字典 .items 方法,用變數的解包分別獲取鍵和值。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_dict = {"name":"菜鳥教學","age":18} return render(request, "runoob.html", {"views_dict": views_dict})
HelloWorld/templates/runoob.html 檔案程式碼:
{% for i,j in views_dict.items %} {{ i }}---{{ j }} {% endfor %}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
在 {% for %} 標籤裡可以通過 {{forloop}} 變數獲取迴圈序號。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_list = ["a", "b", "c", "d", "e"] return render(request, "runoob.html", {"listvar": views_list})
HelloWorld/templates/runoob.html 檔案程式碼:
{% for i in listvar %} {{ forloop.counter }} {{ forloop.counter0 }} {{ forloop.revcounter }} {{ forloop.revcounter0 }} {{ forloop.first }} {{ forloop.last }} {% endfor %}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
{% empty %}
可選的 {% empty %} 從句:在迴圈為空的時候執行(即 in 後面的引數布林值為 False )。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): views_list = [] return render(request, "runoob.html", {"listvar": views_list})
HelloWorld/templates/runoob.html 檔案程式碼:
{% for i in listvar %} {{ forloop.counter0 }} {% empty %} 空空如也~ {% endfor %}
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
可以巢狀使用 {% for %} 標籤:
{% for athlete in athlete_list %} <h1>{{ athlete.name }}</h1> <ul> {% for sport in athlete.sports_played %} <li>{{ sport }}</li> {% endfor %} </ul> {% endfor %}
{% ifequal %} 標籤比較兩個值,當他們相等時,顯示在 {% ifequal %} 和 {% endifequal %} 之中所有的值。
下面的例子比較兩個模板變數 user 和 currentuser :
{% ifequal user currentuser %} <h1>Welcome!</h1> {% endifequal %}
和 {% if %} 類似, {% ifequal %} 支援可選的 {% else%} 標籤:8
{% ifequal section 'sitenews' %} <h1>Site News</h1> {% else %} <h1>No News Here</h1> {% endifequal %}
Django 註釋使用 {# #}。
{# 這是一個註釋 #}
{% include %} 標籤允許在模板中包含其它的模板的內容。
下面這個例子都包含了 nav.html 模板:
{% include "nav.html" %}
csrf_token 用於form表單中,作用是跨站請求偽造保護。
如果不用{% csrf_token %}標籤,在用 form 表單時,要再次跳轉頁面會報403許可權錯誤。
用了{% csrf_token %}標籤,在 form 表單提交資料時,才會成功。
解析:
首先,向瀏覽器傳送請求,獲取登入頁面,此時中介軟體 csrf 會自動生成一個隱藏input標籤,該標籤裡的 value 屬性的值是一個隨機的字串,使用者獲取到登入頁面的同時也獲取到了這個隱藏的input標籤。
然後,等使用者需要用到form表單提交資料的時候,會攜帶這個 input 標籤一起提交給中介軟體 csrf,原因是 form 表單提交資料時,會包括所有的 input 標籤,中介軟體 csrf 接收到資料時,會判斷,這個隨機字串是不是第一次它發給使用者的那個,如果是,則資料提交成功,如果不是,則返回403許可權錯誤。
1、在 app 目錄下建立 templatetags 目錄(目錄名只能是 templatetags)。
2、在 templatetags 目錄下建立任意 py 檔案,如:my_tags.py。
3、在該 py 檔案下:
from django import template register = template.Library() #register的名字是固定的,不可改變
4、利用裝飾器 @register.filter 自定義過濾器。
注意:裝飾器的引數最多隻能有 2 個。
@register.filter def my_filter(v1, v2): return v1 * v2
5、利用裝飾器 @register.simple_tag 自定義標籤。
@register.simple_tag def my_tag1(v1, v2, v3): return v1 * v2 * v3
6、在使用自定義標籤和過濾器前,要在 html 檔案 body 的最上方中匯入該 py 檔案。
{% load my_tags %}
7、在 HTML 中使用自定義過濾器。
{{ 11|my_filter:22 }}
8、在 HTML 中使用自定義標籤。
{% my_tag1 11 22 33 %}
9、語意化標籤
在該 py 檔案中匯入 mark_safe。
from django.utils.safestring import mark_safe
定義標籤時,用上 mark_safe 方法,令標籤語意化,相當於 jQuery 中的 html() 方法。
和前端HTML檔案中的過濾器 safe 效果一樣。
@register.simple_tag def my_html(v1, v2): temp_html = "<input type='text' id='%s' class='%s' />" %(v1, v2) return mark_safe(temp_html)
在HTML中使用該自定義標籤,在頁面中動態建立標籤。
{% my_html "zzz" "xxx" %}
1、在專案根目錄下建立 statics 目錄。
2、在 settings 檔案的最下方設定新增以下設定:
STATIC_URL = '/static/' # 別名 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "statics"), ]
3、在 statics 目錄下建立 css 目錄,js 目錄,images 目錄,plugins 目錄, 分別放 css檔案,js檔案,圖片,外掛。
4、把 bootstrap 框架放入外掛目錄 plugins。
5、在 HTML 檔案的 head 標籤中引入 bootstrap。
注意:此時參照路徑中的要用組態檔中的別名 static,而不是目錄 statics。
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" rel="external nofollow" >
在模板中使用需要加入 {% load static %} 程式碼,以下範例我們從靜態目錄中引入圖片。
HelloWorld/HelloWorld/views.py 檔案程式碼:
from django.shortcuts import render def runoob(request): name ="菜鳥教學" return render(request, "runoob.html", {"name": name})
HelloWorld/templates/runoob.html 檔案程式碼:
{% load static %} {{name}}<img src="{% static "images/runoob-logo.png" %}" alt="runoob-logo">
再存取存取 http://127.0.0.1:8000/runoob,可以看到頁面:
模板可以用繼承的方式來實現複用,減少冗餘內容。
網頁的頭部和尾部內容一般都是一致的,我們就可以通過模板繼承來實現複用。
父模板用於放置可重複利用的內容,子模板繼承父模板的內容,並放置自己的內容。
標籤 block...endblock: 父模板中的預留區域,該區域留給子模板填充差異性的內容,不同預留區域名字不能相同。
{% block 名稱 %} 預留給子模板的區域,可以設定設定預設內容 {% endblock 名稱 %}
子模板使用標籤 extends 繼承父模板:
{% extends "父模板路徑"%}
子模板如果沒有設定父模板預留區域的內容,則使用在父模板設定的預設內容,當然也可以都不設定,就為空。
子模板設定父模板預留區域的內容:
{ % block 名稱 % } 內容 {% endblock 名稱 %}
接下來我們先建立之前專案的 templates 目錄中新增 base.html 檔案,程式碼如下:
HelloWorld/templates/base.html 檔案程式碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鳥教學(runoob.com)</title> </head> <body> <h1>Hello World!</h1> <p>菜鳥教學 Django 測試。</p> {% block mainbody %} <p>original</p> {% endblock %} </body> </html>
以上程式碼中,名為 mainbody 的 block 標籤是可以被繼承者們替換掉的部分。
所有的 {% block %} 標籤告訴模板引擎,子模板可以過載這些部分。
runoob.html 中繼承 base.html,並替換特定 block,runoob.html 修改後的程式碼如下:
HelloWorld/templates/runoob.html 檔案程式碼:
{%extends "base.html" %} {% block mainbody %} <p>繼承了 base.html 檔案</p> {% endblock %}
第一行程式碼說明 runoob.html 繼承了 base.html 檔案。可以看到,這裡相同名字的 block 標籤用以替換 base.html 的相應 block。
重新存取地址 http://127.0.0.1:8000/runoob,輸出結果如下:
到此這篇關於Django框架模板用法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45