1. 程式人生 > >django學習筆記-模板層

django學習筆記-模板層

模板層

將Python嵌入到HTML中。

模板簡介

將HTML硬解碼到檢視並不是那麼完美原因如下:

  • 對頁面設計時也需要對python程式碼進行相應的修改,模板可以不就行python程式碼修改的情況下變更設計。
  • 編寫python和HTML設計是兩項不同的工作,應該明確分工。
  • 兩項同時進行效率最高。

模板:HTML程式碼+模板語法

def current_time(req):
    # ================================原始的檢視函式
    # import datetime
    # now=datetime.datetime.now()
    # html="<html><body>現在時刻:<h1>%s.</h1></body></html>" %now
    # return HttpResponse(html)
    
    #另一種寫法(推薦)
    import datetime
    now=datetime.datetime.now()
    return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})

模板語法的重點:

變數:{{ 變數名 }}
    1.深度查詢用句點符
    2.過濾器
標籤:{%  %}

二、模板語言的註釋

{# this won't be rendered #}  單行註釋

註釋多行使用comment標籤

三、模板語法之變數

在django模板中遍歷複雜資料結構的關鍵是句點字元,語法:{{ 變數名 }}。變數類似於python中的變數。

變數的命名包括任何字母數字以及下劃線("_")的組合。點(".")也有可能會在變數名中出現,不過它有特殊的含義。最重要的是,變數名稱中不能有空格或標點符號。

views.py:

name='abc'
age=18
li=[1,2,'3','4']
dic={'name':'abc','age':18,''li:[1,2,4]}
def test():  #函式
    print('abc')
    return 'abchahahah'
class Person():
    def __init__(self,name,age)
        self.name=name
        self.age=age
    def get_name(self):
        return self.name
    @classmethod
    def cls_test(cls):
        return 'cls'
    @staticmethod
    def static_test():
        return 'static'
    ---------
    # 模板裡不支援帶引數
    def get_name_cs(self,ttt):
        return self.name
    ----------
    
zfj=Person('zfj',18)
qer=Person('qwe',28)
person_list=[zfj,qwe]

html:

相當於print了該變數

<p>字串:{{ name }}</p>
<p>數字:{{ age }}</p>
<p>列表:{{ li }}</p>
<p>元祖:{{ tu }}</p>
<p>字典:{{ dic }}</p>
<p>函式:{{ test }}</p>  {#只寫函式名:相當於函式名(),返回函式執行結果#}
<p>物件:{{ zfj }}</p>   {#物件記憶體地址#}

深度查詢:

<p>列表第1個值:{{ ll.0 }}</p>
<p>列表第4個值:{{ ll.3 }}</p>
<p>字典取值:{{ dic.name }}</p>
<p>字典取列表值:{{ dic.li }}</p>
<p>物件取資料屬性:{{ zfj.name }}</p>
<p>物件取繫結給物件的函式屬性:{{ zfj.get_name }}</p>
<p>物件取繫結給類的函式屬性:{{ zfj.cls_test }}</p>
<p>物件取靜態方法:{{ zfj.static_test }}</p>

四、模板語言之過濾器

語法:

{{變數名|過濾器名稱:屬性值}}

過濾器可以“連結”,一個過濾器的輸出應用於下一個過濾器{{text|escape|linebreaks}},先轉移文字內容,然後把文字轉成<p>標籤。

注:過濾器引數包含空格,必須用引號抱起來。

1.過濾器總覽

過濾器 說明
add 加法
addslashes 新增斜槓
capfirst 首字母大寫
center 文字居中
cut 切除字元
date 日期格式化
default 設定預設值
default_if_none 為None設定預設值
dictsort 字典排序
dictsortreversed 字典反向排序
divisibleby 整除判斷
escape 轉義
escapejs 轉義js程式碼
filesizeformat 檔案尺寸人性化顯示
first 第一個元素
floatformat 浮點數格式化
force_escape 強制立刻轉義
get_digit 獲取數字
iriencode 轉換IRI
join 字元列表連結
last 最後一個
length 長度
length_is 長度等於
linebreaks 行轉換
linebreaksbr 行轉換
linenumbers 行號
ljust 左對齊
lower 小寫
make_list 分割成字元列表
phone2numeric 電話號碼
pluralize 複數形式
pprint 除錯
random 隨機獲取
rjust 右對齊
safe 安全確認
safeseq 列表安全確認
slice 切片
slugify 轉換成ASCII
stringformat 字串格式化
striptags 去除HTML中的標籤
time 時間格式化
timesince 從何時開始
timeuntil 到何時多久
title 所有單詞首字母大寫
truncatechars 截斷字元
truncatechars_html 截斷字元
truncatewords 截斷單詞
truncatewords_html 截斷單詞
unordered_list 無序列表
upper 大寫
urlencode 轉義url
urlize url轉成可點選的連結
urlizetrunc urlize的截斷方式
wordcount 單詞計數
wordwrap 單詞包裹
yesno 將True,False和None,對映成字串‘yes’,‘no’,‘maybe’

2.常用過濾器

default

如果變數是false或者為空,則使用給定的預設值。

{{ value|default:'nothing'}}

length

返回值的長度,對字串和列表都起作用

{{ value|length}} 如果value是[1,2,3,4],那麼輸出是4

filesizeformat

將值格式化成'人類可讀的'檔案尺寸。例如:
{{1024|filesizeformat}}  輸出為1kb

date

如果value=datetime.datetime.now()

{{ value|date:"Y-m-d"}}

slice

切片

{{ name|slice:'0:3:3' }}

truncatechars

如果字串多餘指定字元數量,多餘會被截斷,替換成("...")結尾。

{{ value|truncatechars:9}}

safe

Django模板為了安全預設會對HTML標籤和js等語法標籤進行轉義,有時候我們不希望這些元素被轉義,可以通過設定過濾器。

script="'<script>alert(111)</script>"
{{ script|safe }}

五、模板之標籤

一些在輸出中建立文字,一些通過迴圈或邏輯來控制流程,一些載入其後的變數將使用到的額外資訊到模版中。一些標籤需要開始和結束標籤 (例如{% tag %} ...標籤 內容 ... {% endtag %})。
{% tag %}

1.內建標籤總覽

標籤 說明
autoescape 自動轉義開關
block 塊引用
comment 註釋
csrf_token CSRF令牌
cycle 迴圈物件的值
debug 除錯模式
extends 繼承模版
filter 過濾功能
firstof 輸出第一個不為False的引數
for 迴圈物件
for … empty 帶empty說明的迴圈
if 條件判斷
ifequal 如果等於
ifnotequal 如果不等於
ifchanged 如果有變化,則..
include 匯入子模版的內容
load 載入標籤和過濾器
lorem 生成無用的廢話
now 當前時間
regroup 根據物件重組集合
resetcycle 重置迴圈
spaceless 去除空白
templatetag 轉義模版標籤符號
url 獲取url字串
verbatim 禁用模版引擎
widthratio 寬度比例
with 上下文變數管理器

2.常用標籤

for標籤

遍歷每一個元素

{% for person in person_list %}
    <p>{{ person }}</p>
{% end for%}

遍歷一個字典:

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

下面是Django為for標籤內建的一些屬性,可以當作變數一樣使用{{ }}在模版中使用。

  • forloop.counter:迴圈的當前索引值,從1開始計數;常用於生成一個表格或者列表的序號!
  • forloop.counter0:迴圈的當前索引值,從0開始計數;
  • forloop.revcounter: 迴圈結束的次數(從1開始)
  • forloop.revcounter0 迴圈結束的次數(從0開始)
  • forloop.first:判斷當前是否迴圈的第一次,是的話,該變數的值為True。我們經常要為第一行加點特殊的對待,就用得上這個判斷了,結合if。
  • forloop.last:如果這是最後一次迴圈,則為真
  • forloop.parentloop:對於巢狀迴圈,返回父迴圈所在的迴圈次數。某些場景下,這是個大殺器,能解決你很多頭疼的問題。

for...empty

for標籤帶有一個可選的{% empty %}從句,在給出的組是空的或者沒有被找到時執行的操作

注:迴圈的物件是空,才會走到empty,而不是物件裡面的東西為空

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

if

{% if %}會對一個變數求值,如果它的值是“True”(存在、不為空、且不是boolean型別的false值),對應的內容塊會輸出。

{% if num > 100 or num < 0 %}
    <p>無效</p>
{% elif num > 80 and num < 100 %}
    <p>優秀</p>
{% else %}
    <p>湊活吧</p>
{% endif %}

注:在if標籤中使用括號是錯誤的語法,這點不同於Pythonif語句支援 ,優先順序可以使用if巢狀。if支援and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。

with

使用一個簡單地名字快取一個複雜的變數,當你需要使用一個“昂貴的”方法(比如訪問資料庫)很多次的時候是非常有用的

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

六、自定義標籤和過濾器

Django為我們提供了自定義的機制,可以通過使用Python程式碼,自定義標籤和過濾器來擴充套件模板引擎,然後使用{% load %}標籤。

(一)、前置步驟

  1. 在settings中的INSTALLED_APPS配置當前app,不然django無法找到自定義的simple_tag.

  2. 在app中新建一個templatetags包(名字固定),與views.py、models.py等檔案在同一目錄下

    注:新增templatetags包後,需要重新啟動伺服器,然後才能在模板中使用標籤或過濾器

  3. 建立任意 .py 檔案,如:my_tags.py

  4. 要在模組內自定義標籤,首先,這個模組必須包含一個名為register的變數,它是template.Library的一個例項,所有的標籤和過濾器都是在其中註冊的。 所以把如下的內容放在你的模組的頂部:

from django.template import Library
register = Library()

templatetags包中放多少個模組沒有限制。只需要記住{% load xxx %}將會載入給定模組名中的標籤/過濾器,而不是app中所有的標籤和過濾器。

(二)、自定義模板過濾器

1.編寫過濾器

自定義過濾器就是一個帶有一個或兩個引數的python函式

注:函式的第一個引數是要過濾的物件,第二個是自定義引數,函式一共只能有兩個引數。

  • 變數的值:不一定是字串形式
  • 可以有一個初始值,或者不需要這個引數

例子:

def filter_multi(v1,v2):
    return  v1 * v2

2.註冊過濾器

定義好過濾器函式之後,需要註冊,方法是呼叫register.filter

register.filter('filter_multi',filter_multi)

Library.filter()方法需要兩個引數:

  • 過濾器的名稱:一個字串物件
  • 編譯的函式 :你剛才寫的過濾器函式

還可以把register.filter()用作裝飾器,以如下的方式註冊過濾器:

@register.filter(name='yyy')
注:沒有宣告name引數,Django將使用函式名作為過濾器的名字。

3.過濾器的使用方法

  1. 在要使用自定義過濾器的模板中匯入建立的py檔案。

    語法:{% load 檔名 %}

  2. 要使用的地方。{{'abc'|yyy:'qwe'}} 結果輸出abcqwe

(三)、自定義模板標籤

除了裝飾器,其它步驟與自定義過濾器相似。

@register.simple_tag()

過濾器只能有兩個引數,自定義標籤可以傳多個值,空格傳值。

注:過濾器可以用在if判斷中,標籤不能

七、模板繼承

模版繼承可以讓您建立一個基本的“骨架”模版,它包含您站點中的全部元素,並且可以定義能夠被子模版覆蓋的 blocks 。

1.模板匯入

語法:{% include'模板名稱' %}

如:{% include 'base.html' %}

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css"/>
    <title>{% block title %}My amazing site{% endblock %}</title>
</head>

<body>
<div id="sidebar">
    {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    {% endblock %}
</div>

<div id="content">
    {% block content %}{% endblock %}
</div>
</body>
</html>

它定義了一個可以用於兩列排版頁面的簡單HTML骨架。“子模版”的工作是用它們的內容填充空的blocks。

2.子模板中使用

語法:
{% block名字 %}
    子模板的內容
{% endblock %}
{% block content %}
    <p>這是子的區域</p>
    <p>這是子的區域</p>
    <p>這是子的區域</p>
    <p>這是子的區域</p>
{% endblock content%}

注:

  • 如果在模板中使用{% extends %}標籤,它必須是模板中的第一個標籤
  • 在base模板中設定越多的{% block %}標籤越好,子模板不必定義全部父模板中的blocks
  • 如果發現有大量的模板存在重複內容,可以定義在父模板的{% block %}中。
  • 不能再一個模板中定義多個相同名字的block標籤
  • 為了更好的可讀性,可以給{% endblock %}設定一個名字
{% block content %}
{% endblock content%}

八、靜態檔案相關

  1. 寫死靜態檔案:

  2. 使用 static標籤函式:

    {% load static %}
    <link rel="stylesheet" href="{% static 'css/mycss.css' %}">
  3. 使用get_static_prefix 標籤

    {% load static %}
    <link rel="stylesheet" href="{% get_static_prefix %}css/mycss.css">