Web框架之Django_04 模板層瞭解(過濾器、標籤、自定義過濾器、標籤、inclusion_tag、模板的繼承與導入)

摘要:

模版層(模板語法)

  • 模板語法

  • 過濾器

  • 標籤

  • 自定義過濾器、標籤

  • inclusion_tag

  • 模板的繼承

  • 模板的導入

1、模板語法:

  1. 經常使用語法:
    {{     }}    變量相關
    {% %}    邏輯相關
  2. 變量:
    在Django中的模板語言用{{ 變量名 }}來使用變量,而這個變量的來源一般是在視圖函數裏面產生的,經過render方法返回到前端,前端經過此語法來使用該變量。
    後端向前端頁面傳遞數據的方式:
    # 第一種:
    return render(request,'index.html',{'n':n})
    # 第二種:
    return render(request,'index.html',locals())  
    # 將當前所在的名稱空間中的名字所有傳遞給前端頁面

    後端的傳遞的數據類型能夠是:int、str、list、dict、tuple、set、function....
    傳遞的變量命名規則:包括任何字母數字以及下劃線 ("_")的組合, 變量名稱中不能有空格或標點符號。
    模板語法規定:使用句點符(就是點號:.)來取出變量中的相關數據,好比字典、列表、元祖、屬性方法(對象)
    這裏還須要強調一點:模板語法是不支持傳參的。
    模板中支持的寫法:css

    後端:views.py
    l = [1,2,3,4,5,user_obj]
    user_obj = models.Book.object.filter(id=1).first()
    d = {'name': 'sgt', 'password': '123'}
    
    前端:使用模板語法,來處理後端傳遞過來的變量
    
    {# 取l中的第一個參數 #}
    {{ l.0 }}
    {# 取字典d中相應的值 #}
    {{ d.name }}
    {{ d.keys }}
    {{ d.values }}
    {{ d.items }}
    
    {# 取對象的name屬性 #}
    {{ user_obj.name }}
    
    {# .操做只能調用不帶參數的方法 #}
    {{ l.5.name }}
    
    {% with l.5.name  as h %}
    {{ h }}
    {% endwith %}
    {# 將 l.5.name找到的數據起名爲h,這樣就能夠經過h這個名字獲得 l.5.name的值 #}

    這裏特別來講說把
    函數:html

    後端:
    def func():
            return '你調用了我?'
    
    前端:
    {{ func }}
    
    顯示結果:你調用了我?
    
    在前端調用後端的函數名(固然此函數名確定在locals()裏面)時,會調用該函數(函數名加括號),獲得函數調用的返回值,若是無返回值則爲None

    類:前端

        後端

    class Demo(object): def __init__(self, name): self.name = name def func(self): return self.name @classmethod def test(cls): return 'cls' @staticmethod def foo(name,age): return 'static_foo' obj = Demo('sgt')
    <app01.views.ttt.<locals>.Demo object at 0x0000024052F39898>
    cls
    sgt
    sgt

    若是類裏面加入:django

            def __str__(self):
                return 'Sgt帥得一塌糊塗!'

    那麼{{ obj }}的結果就會變成:Sgt帥得一塌糊塗!(由於__str__會攔截打印動做,在前端{{ obj }}實際上就是相似於打印obj.後端

 2、過濾器:(Filters)

  1. 經常使用過濾器介紹:
    在Django的模板語言中,經過使用 過濾器 來改變變量的顯示。安全

    過濾器的語法: {{ value|filter_name:參數 }}app

    使用管道符"|"來應用過濾器。
    這裏的過濾的意思實際上我的認爲概念很模糊,過濾器的意思是將變量經過使用後端的方法將變量進行相關操做加工邏輯處理的封裝以後拿到前端去使用的一種過程實現。
    例如:{{ name|lower }}會將name變量應用lower過濾器以後再顯示它的值。lower在這裏的做用是將文本全都變成小寫。
    注意事項:
    ##過濾器支持鏈式操做,即一個過濾器的輸出結果做爲另外一個過濾器的輸入
    ##過濾器能夠接收參數,例如:{{ sss|truncatewords:30 }},這將顯示sss的前30個詞。
    ##過濾器參數包含空格的話,必須用引號包裹起來,好比使用逗號和空格去鏈接一個列表中的元素,如:{{ list|join:', ' }}
    ##管道符‘|’左右沒有空格。必定要注意,沒有空格
    Django的模板語言中提供了大約六十個內置過濾器。這裏主要拿出一些常見的方法來介紹:
    #default
    若是一個變量是false或空,使用給定的默認值,不然使用該變量的值。
    ide

    {{ value|default:"nothing"}}
    若是value沒有傳值或者值爲空的話就顯示nothing

    #length
    返回值的長度,做用於字符串和列表
    函數

    {{ value|length }}
    
    後端:
    s = 'what f**k!'
    l = ['a', 'b', 4, 5, 8]
    
    前端:
    {{ l|length }}
    {{ s|length }}
    
    顯示結果:5 10

    #filesizeformat
    將值格式化爲一個可理解的文件大小單位(13kb,4m)oop

    {{ value|filesizeformat }}
    
    後端:
    n = 102478450
    
    前端:
    {{ n|filesizeformat }}
    
    顯示結果:97.7 MB

    #slice 切片(顧頭不顧尾)

    {{value|slice:"開始索引:結束索引:步長"}}
    
    後端:
    s = 'what f**k!'
    l = ['a', 'b', 4, 5, 8]
    
    前端:
    {{ l|slice:'1:4' }} 
    {{ s|slice:'5:9' }}
    {{ l|slice:'2:-1' }}    <!--從索引2開始切,切到索引爲-1的位置爲結尾,同時顧頭不顧尾-->
    
    顯示結果:
    ['b', 4, 5] 
    f**k
    [4, 5]

    #date 時間格式化輸出

    {{ value|date:"Y-m-d H:i:s"}}
    
    後端:
    import datetime
    ctime = datetime.datetime.now()
    
    前端:
    {{ ctime }}
    {{ ctime|date:'Y-m-d H:i:s' }}
    
    顯示結果:
    June 11, 2019, 2:51 p.m. 
    2019-06-11 14:51:24
    a 'a.m.''p.m.' (注意,它與PHP 的輸出略有不一樣.它包括了句點(django擴展). 'a.m.' 
    A 'AM''PM'. 'AM' 
    B 未實現.   
    d 每個月第幾天, 帶前導零 '01' to '31' 
    D 每週第幾天,3字母的字符串. 'Fri' 
    f 時間, 12-小時制的小時和分鐘數, 若是分鐘數爲零,則不顯示.(django 擴展). '1', '1:30' 
    F 月份, 長文本格式. 'January' 
    g 小時, 12-小時制,沒有前導零 '1' to '12' 
    G 小時, 24-小時制,沒有前導零 '0' to '23' 
    h 小時, 12-小時制,有前導零 '01' to '12' 
    H 小時, 24-小時制,有前導零 '00' to '23' 
    i 分鐘. '00' to '59' 
    I 未實現   
    j 每個月第幾天, 無前導零 '1' to '31' 
    l 每週第幾天,長文本格式. 'Friday' 
    L 是否閏年. True or False 
    m 數字表示的月份,有前導零. '01' to '12' 
    M 月份,3字母短文本格式. 'Jan' 
    n 數字表示的月份,無前導零 '1' to '12' 
    N 出版風格的月份縮寫(django 擴展) 'Jan.', 'Feb.', 'March', 'May' 
    O 與格林威治的時間差(以小時計) '+0200' 
    P 12小時制的小時分鐘及'a.m.'/'p.m.' 分鐘數若爲零則不顯示. 用字符串表示特殊 的時間點, 如 'midnight''noon' (django擴展) '1 a.m.', '1:30 p.m.', 'midnight','noon', '12:30 p.m.' 
    r RFC 822 格式的日期 . 'Thu, 21 Dec 2000 16:01:07+0200' 
    s 秒數, 帶有前導零的數字表示 '00' to '59' 
    S 英語序數後綴,用於一個月的第幾天,2個字符 'st', 'nd', 'rd' or 'th' 
    t 給定月共有多少天. 28 to 31 
    T 本機時區. 'EST', 'MDT' 
    U 未實現   
    w 一週中的第幾天,沒有前導零的數字 '0' (Sunday) to '6' (Saturday) 
    W ISO-8601 一年的第多少星期數, 一週從 星期一開始 1, 23 
    y Year, 2 位數字表示 '99' 
    Y Year, 4 位數字表示 '1999' 
    z 一年中的第幾天 . 0 to 365 
    Z 以秒計的時區偏移量. 這個偏移量對UTC西部 時區老是負數,而對UTC東部時區則老是正數 -43200 to 43200
    日期格式化參數

    #safe

    Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。

    後端:
    value = "<a href='https://www.cnblogs.com/suguangti/'>點我</a>"
    
    前端:
    {{ value }}
    {{ value|safe }}
    
    結果:
    <a href='https://www.cnblogs.com/suguangti/'>點我</a> 
    點我
    
    下面那個‘點我’在頁面上是一個a標籤,點擊可跳轉

    上面的safe是在前端取消轉義,後端取消轉義方法以下:

    from django.utils.safestring import mark_safe
    xxx = mark_safe('<h1>我是h1標籤</h1>')

    #truncatechars
    若是字符串字符多於指定的字符數量,那麼會被截斷,截斷的剩餘字符將用省略號結尾表示。
    參數:截斷的字符數(包含三個點)

    後端:
    ss = 'abcdefghijklmnopqrstuvwxyz'
    
    前端:
    {{ ss|truncatechars:10 }}
    
    結果:(注意...也算進長度裏了)
    abcdefg...

    #truncatewords
    以一個單詞爲一個元素,單詞與單詞之間的空格爲區分依據,將必定數量的單詞進行截斷,截斷後面的用...表示
    一個單詞加上一個空格  計數一個

    後端:
    sss = "Life was like a box of chocolates you never know what you're gonna get."
    
    前端:
    {{ sss|truncatewords:7 }}
    
    顯示結果:
    Life was like a box of chocolates ...
    (注意chocolates後面有個空格)

     #cut

    移除變量中全部的指定相同的字符串

    {{ value|cut:' ' }}
    
    後端:
    ssss = 'you do bb now,bb is not good thing, why do you bb for too many times!'
    
    前端:
    {{ ssss|cut:'bb' }}
    
    顯示結果:
    you do now, is not good thing, why do you for too many times!

    #join
    將列表中的元素用指定字符鏈接起來

    後端
    ll = [1, 2, 3, 4, 5]
    
    前端
    {{ ll|join:'@' }}
    
    結果
    1@2@3@4@5
  2. 標籤介紹:
    #for循環(內部有個empty判斷,詳見下面if判斷示例)
    後端
    ll = [1, 2, 3, 4, 5]
    
    前端
    {% for foo in ll %}
         <p>{{ foo }}</p>
    {% endfor %}
    
    結果顯示:
    1
    2
    3
    4
    5

    forloop的使用:

    後端
    ll = [1, 2, 3, 4, 5]
    
    前端
    {% for foo in ll %}
         <p>{{ forloop }}</p>
    {% endfor %}

    forlop裏面有幾個屬性須要咱們注意,好比 counter0,counter,first,last它們對應的值在for循環過程當中的開始和結束是不同的
    #if 判斷

    {% for foo in l %}
    if else
        {% if flag %}
            <p>flag不爲空</p>
            {% else %}
            <p>flag是空</p>
        {% endif %}
        
    {#(l = ['a', 'b', 'c', 'd', 'e'])#}
    {% for foo in l %}
        {% if forloop.first %}
            <p>這是個人第一次</p>
        {% elif forloop.last %}
            <p>這是最後一次了啊</p>
        {% else %}
            <p>嗨起來!!!</p>
        {% endif %}
        {% empty %}   <!--若是l = [],上面的for循環不會進行,只會走這一步-->
            <p>你給個人容器類型是個空啊,無法for循環</p>
    {% endfor %}
    l = ['a', 'b', 'c', 'd', 'e']
    這是個人第一次
    嗨起來!!!
    嗨起來!!!
    嗨起來!!!
    這是最後一次了啊
    
    l = []
    你給個人容器類型是個空啊,無法for循環
  3. 自定義過濾器/標籤/inclusion_tag:

    必須作的三件事
    1.在應用名下新建一個名爲templatetags文件夾(必須叫這個名字)
    2.在該新建的文件夾內新建一個任意名稱的py文件
    3.在該py文件中須要固定寫下面兩句代碼
    ①這裏在app01項目程序文件夾新建templatetags文件夾,在此文件夾內新建一個mine.py文件,打開mine.py文件>>輸入:

    from django import template
    register = template.Library()
    
    # 自定義過濾器
    @register.filter(name='my_filter')
    def index(a, b):
        return a*b
    
    # 自定義標籤:
    @register.simple_tag
    def plus(a, b, c):
        return a+b+c

    ②前端html文件內使用過濾器或者標籤:

    {% load mine %}   <!-- 要使用自定義過濾器和標籤,須要先加載本身定義的文件 -->
    {{ 9|my_filter:11 }}  <!-- 使用自定義過濾器,注意這裏須要用name的值做爲使用方法 -->
    {% my_tag 1 2 3 %}  <!-- 使用自定義標籤,注意這裏須要用name的值做爲使用方法 -->

    顯示的結果:

    99
    6

     自定義inclusion_tag

     inclusion_tag的做用:建立一個動態的html頁面文件a.html,這個頁面文件a能夠在另一個頁面b中被調用,實現這個頁面a應該有的功能。好比:
    在上面的mine.py文件中建立inclusion_tag:

    # mine.py文件  建立inclusion_tag
    
    from app01 import models 
    from django import template
    register = template.Library()
    
    @register.inclusion_tag('inclusion_t_test.html', name='my_inclusion')
    def func():
        book_list = models.Book.objects.all()
        return {'list': book_list} 
    
    #將book_list的QuerySet對象列表傳進inclusion_t_test.html文件

    inclusion_t_test.html文件裏面:

    <!-- inclusion_t_test.html文件,被導入的html文件-->
    <table>
        <thead>
            <tr>
                <th>id</th>
                <th>title</th>
                <th>price</th>
            </tr>
        </thead>
        <tbody>
            {% for obj in list %}
                <tr>
                    <td>{{ obj.id }}</td>
                    <td>{{ obj.title }}</td>
                    <td>{{ obj.price }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>

    調用的html頁面文件:

    {% load mine %}    <!-- 必需要先加載建立標籤的文件-->
    {% my_inclusion %}  <!-- 調用inclusion_t_test.html頁面文件,這裏使用該標籤的name來調用-->

3、模板的繼承與模板的導入

  • 模板的繼承:
    繼承的概念咱們都知道:在類裏面是直接可使用基類中的屬性和方法,也就是直接能用,不須要本身再寫的意義。
    而模板的繼承:咱們須要使用一個網頁中一些固定不變的部分,再不用再本身寫或者複製的前提下,只須要寫幾段代碼就能拿來在一個新的網頁使用,就像一個模板,模板中變化的地方咱們本身指定,其餘地方不變,值只變化咱們指定的地方。
    實現過程:
    首先須要在被繼承的模板中劃分多個區域,這些區域是咱們能的可變更區
    {% block 給區域起的名字 %}
    
    {% endblock %}
    
    <!--一般狀況下一個模板中應該至少有三塊-->
    {% block css %}
      頁面css代碼塊
    {% endblock %}
    
    {% block js %}
      頁面js代碼塊
    {% endblock %}
    
    {% block content %}
      頁面主體內容
    {% endblock %}
    子板繼承模板:
    {#先繼承模板全部的內容#}
            {% extends 'home.html' %}
    
    {#而後根據block塊的名字修改指定區域的內容#}
            {% block content %}
                <h1>登陸頁面</h1>
                    <form action="">
                        <p>username:<input type="text" class="form-control"></p>
                        <p>password:<input type="text" class="form-control"></p>
                        <input type="submit" class="btn btn-success">
                    </form>
            {% endblock %}

    若是在一個block模板中須要保留原始的內容則能夠在這個block中任意你想要的位置添加一個{{ block.super }},就能夠保留原內容
  • 模板的導入
    將一段html當作模塊的方式導入到另外一個html展現
    {% include '想導入的html文件名' %}

    模板導入與自定義inclusion_tag的區別:模板導入的頁面內容是靜態的、不變的,而經過自定義inclusion_tag導入的頁面文件能夠是動態的,可動性本身掌控。

    補充:靜態文件配置

    {% load static %}  
        
        <link rel='stylesheet' href="{% static 'css/mycss.css'%}">  # 第一種方式
        <link rel='stylesheet' href="{% get_static_prefix %}css/mycss.css">  # 第二種方式
相關文章
相關標籤/搜索