Django之深刻了解模板層

模板語法

前端模板的語法只記住兩種就好了。html

{{ xxx }} 變量相關的
{ %  % } 邏輯相關的

模板傳值

咱們經過後端,能夠傳給前端的數據,數據類型哪些可以接收,哪些不能接收?前端

前端基本上能接受全部後端全部的數據類型。python

只要是後端可以加括號調用的,傳遞到html頁面上都會自動加括號調用,可是若是是 函數有形參就不能調用了,html頁面也不能傳參。django

views.py:
def test(request):
    a = 1
    b = 1.11
    c = 'str'
    d = [11,22]
    e = (11,22)
    s = {11,22}
    f = {"user":'age'}
    g = True

    def test1():
        return 'ok'

    class test2(object):
        def get_self(self):
            return 'get_self'

        @classmethod
        def get_cls(cls):
            return 'get_cls'

        @staticmethod
        def get_func():
            return 'get_func'
    obj = test2()

    # 咱們以前是經過這種方式來給前端傳值的,若是須要傳的值很是的多的話,這樣寫就比較麻煩,
    # return render(request,'test.html',{"a":a})
    # 能夠經過locals()這種方式,將當前全部的名稱空間中的名字都傳給前端。
    return render(request,'test.html',locals())


test.html:
<body>
# 接收普通變量
<h1>{{ a }}</h1>
<h1>{{ b }}</h1>
<h1>{{ c }}</h1>
<h1>{{ d }}</h1>
<h1>{{ e }}</h1>
<h1>{{ f }}</h1>
<h1>{{ g }}</h1>
<h1>{{ s }}</h1>    

# 接收函數
<h1>{{ test1 }}</h1>    

# 接收類
<h1>{{ test2 }}</h1>

# 接收對象
<h1>{{ obj }}</h1>

# 對象.方法調用
<h1>{{ obj.get_self }}</h1>
<h1>{{ obj.get_cls }}</h1>
<h1>{{ obj.get_func }}</h1>
</body>

# 打印結果:
1
1.11
str
[11, 22]
(11, 22)
{'user': 'age'}
True
{11, 22}
ok
<app01.views.test.<locals>.test2 object at 0x000000000BAD11D0>
<app01.views.test.<locals>.test2 object at 0x000000000BA9ADD8>
get_self
get_cls
get_func

過濾器

什麼是過濾器?後端

模板語法中,提供給你了一些內置的方法,幫你快速的處理後端傳過來的數據。這個是模板語法的過濾器。app

過濾器 語法結構:xx|xxxx:變量 | 操做函數

常見的一些過濾器:oop

過濾器 描述
length 統計長度
add: 加法運算
slice:'' 切片操做
default: 判斷是否有值,若是沒有值使用默認值
filesizeformat 自動計算文件大小
truncatechars: 截取幾個字符,算上...(三個點)
truncatewords: 按照空格截取幾個單詞,不算...(三個點)
safe 前端展現帶有標籤的文本

有一種後端在傳遞前端數據的時候,若是後端發送了一個數據是帶有html標籤的,是不會自動轉換的,那麼咱們既可使用上面自帶的過濾器轉義,也能夠後端轉移事後在發過來。code

前端轉義:

from django.utils.safestring import mark_safe
sss = '<h2>我是帶有標籤的字符串</h2>'
sss = mark_safe(sss)
return render(request,'test.html',locals())
views.py:

def test(request):
    a = 1
    b = 1.11
    c = 'stdsdsddsdsr'
    d = [11,22]
    e = (11,22)
    s = {11,22}
    f = {"user":'age'}
    g = True
    is_value = ''
    filesize = 3212144324
    _str = 'dahsdk dsadbukab daku dasn dbda dan dwa wa dwad wawd w'
    sss = '<h2>我是帶有標籤的字符串</h2>'
    sss = mark_safe(sss)
    return render(request,'test.html',locals())

test.html:

<h1>
模板語法中的過濾器會自動將|左邊的數據當作右邊過濾器的第一個參數傳進去
過濾器其實就是個函數 def length(value):
</h1>
<h1>統計c的長度:{{ c|length }}</h1> # 其實源碼中就是 len(value)
<h1>加法運算:{{ a|add:10 }}</h1>
<h1>切片操做,顧頭不顧尾:{{ c|slice:'0:2' }}</h1>
<h1>判斷變量是否有值(有值展現值自己,沒有值展現默認值):{{ is_value|default:'is_value變量名的值爲空' }}</h1>
<h1>自動轉大小格式:{{ filesize|filesizeformat }}</h1>  # 自動轉大小格式:3.0 GB
<h1>截取文本的內容(字符),截取五個字符,三個點也算:{{ c|truncatechars:5 }}</h1>
<h1>截取文本的內容(按照空格計算),截取五個字符,三個點不算:{{ c|truncatewords:5 }}</h1>
<h1>默認狀況下,若是後端發送了一個數據是帶有html標籤的,是不會自動轉換的
是由於放置惡意攻擊,若是有腳本執行了就完蛋了。</h1>
<h1>展現帶有標籤的文本:{{ sss }}</h1>

標籤

標籤是一些邏輯相關的,好比for循環,if判斷。

語法結構:{ % % }

僞代碼例子

{% for foo in c %}
    {% if forloop.first %}
        <p>這是第一個值 {{ foo }}</p>
    {% elif forloop.last %}
        <p>這是最後一個值 {{ foo }}</p>
    {% else %}
        <p>{{ foo }}</p>
    {% endif %}
    {% empty %}
        <p>當for循環的對象時空的時候會走這個</p>
{% endfor %}

若是後端傳過來一些比較複雜的數據:

好比:

comp_dic = {'username': 'jason', 'hobby':
        ['read', 'study',
         ['run', 'rap', {'age': 18}]
         ]
                }

我想要提取出年齡:
模板語法只有一種方式取值:統一採用句點符(點點點方式)
<h1>{{ comp_dic.hobby.2.2.age }}</h1>
18

那麼當這個數是經過比較複雜的點點點獲取到的,
後續又須要常常使用,能夠給該數據起一個別名,
別名只能在with內部使用
{% with comp_dic.hobby.2.2.age as age  %}
    <h1>{{ age }}</h1>
{% endwith %}

自定義過濾器和標籤

django支持用戶自定義本身的過濾器和標籤

自定義的必需要有三步準備:

  1. app名下新建一個名字必須交templatetags的文件及
  2. 在該文件夾內新建一個py文件,名字隨便起
  3. 在該py文件中必須寫下面兩句代碼
# 必須寫
from django.template import Library
register = Library()

# 自定義的過濾器函數
# 起個別名:bady,跟默認的過濾器同樣,最多隻能接收兩個參數
@register.filter(name='bady')
def minus(a,b):
    return a - b

# 自定義標籤,能夠接收任意多個參數
@register.simple_tag(name='mytag')
def mytag(a,b,c,d):
    return '%s ? %s ? %s ? %s ?' % (a,b,c,d,)

# 自定義inclusion_tag
# inclusion_tag的做用是主頁面以必定的語法給一個參數,調用某個函數,這個函數能夠經過主頁面給的參數作一些邏輯處理獲得一些數據,將數據渲染到一個小html模塊,而後將渲染後的小html模塊返回給主頁面渲染在調用的位置。mytag.html就是臨時的一個小頁面渲染
@register.inclusion_tag('mytag.html',name='myinclusion_tag')
def myinclusion_tag(n):
    l = []
    for i in range(n):
        l.append('第%s項'%i)
    return locals()

mytag.html:
<ul>
{% for foo in l %}
    <li>{{ foo }}</li>
{% endfor %}
</ul>

實現效果:
* 第0項
* 第1項
8 第2項
* 第3項
* 第4項
* 第5項
* 第6項
* 第7項
* 第8項
* 第9項

使用自定義的過濾器

須要先在html頁面上加載

<h1>自定義過濾器的使用</h1>
{% load mytag %}
{{ 2|bady:1 }}  1
{{ 10|bady:2 }} 8

<h1>自定義標籤的使用</h1>
{% load mytag %}
{% mytag '1' '2' '3' '4' %}     1 ? 2 ? 3 ? 4 ?


使用自定義的標籤作邏輯判斷
{% if 2|bady:2 %}
    <p>{{ 2|bady:2 }}</p>
{% else %}
    <p>0</p>
{% endif %}

不能不能   !!!!使用自定義的標籤作邏輯判斷
{% if mytag '1' '2' '3' '4' %}
    <p>有值</p>
{% else %}
    <p>無值</p>
{% endif %}


<h1>自定義的inclusion_tag的使用
當你須要使用一些頁面組件的時候,而且該頁面組件須要參數纔可以渲染
能夠考慮使用inclusion_tag</h1>
{% load mytag %}
{% myinclusion_tag 10 %}

模板繼承

當寫好了一個很是漂亮的頁面的時候,其餘頁面也須要使用這個頁面,那麼能夠考慮使用模板的繼承。

須要事先在你想要使用的頁面上 劃定區域 以後在繼承的時候 你就可使用你劃定的區域。
也就意味着 若是你不劃定任何區域 那麼你將沒法修改頁面內容。

{% block content %}
{% endblock %}

<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% block content %}
            {% endblock %}
        </div>
    </div>
</div>

html代碼區域 能夠設置多個block

新建的html文件就能夠繼承以前的模板了

{% extends 'template.html' %}


{% block content %}
    {{ block.super }}
    <div class="jumbotron">
  <h1>Hello, world!</h1>
  <p>...</p>
  <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
{% endblock %}

模板的繼承

  1. 先在你想要繼承的頁面上經過block劃定你未來可能要改的區域
  2. 在子頁面上先繼承extends
  3. 利用block自動提示 選擇你想要修改的內容區域

模板導入

將html頁面當作模塊直接導入使用

{% include 'template.html' %}
相關文章
相關標籤/搜索