十五 django-模板語法

一、概要

對于模版,其實就是讀取模版(其中嵌套著模版標簽),然后將模型中獲取的數據插入到模版中,最后將信息返回給用戶。

官方文檔

二、模板應用

1、說明

只要是在html里面有模板語法就不是html文件了,這樣的文件就叫做模板

本質就是html+模板語法

2、為什么要使用模板

  • 對頁面設計進行的任何改變都必須對 Python 代碼進行相應的修改。 網站設計的修改往往比底層 Python 代碼的修改要頻繁得多,因此如果可以在不進行 Python 代碼修改的情況下變更設計,那將會方便得多。
  • Python 代碼編寫和 HTML 設計是兩項不同的工作,大多數專業的網站開發環境都將他們分配給不同的人員(甚至不同部門)來完成。 設計者和HTML/CSS的編碼人員不應該被要求去編輯Python的代碼來完成他們的工作。
  • 程序員編寫 Python代碼和設計人員制作模板兩項工作同時進行的效率是最高的,遠勝于讓一個人等待另一個人完成對某個既包含 Python又包含 HTML 的文件的編輯工作。

2、基本使用

  1. views.py
    class User:
        def __init__(self, name=None, age=0):
            self.name = name
            self.age = age
      # views      
     def index(request):
           title = "Hello Django"
           num = 110
           li = [1, 2, 3, 4, 5]
           dic = {'name': '小明', 'age': 20}
           user1 = User(name='小明')
           user2 = User(name='小紅')
            user_list = [user1, user2]
           context = {
               'num': num,
               'title': title,
               'li': li,
               'dic': dic,
               'user': user1,
               'user_list': user_list,
           }
       return render(request, 'home/index.html', context)        
    
  2. templates/home/index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="/static/js/jquery-3.3.1.js"></script>
    </head>
    <body>
    <ul>
        <li>數字:{{ num }}</li>
        <li>字符串:{{ title }}</li>
        <li>列表:{{ li.0 }}</li>
        <li>列表:{{ li.1 }}</li>
        <li>列表:{{ li.2 }}</li>
        <li>字典:{{ dic.name }}</li>
        <li>字典:{{ dic.age }}</li>
        <li>對象:{{ user.name }}</li>
        <li>對象:{{ user.age }}</li>
        <li>列表:{{ user_list.1.name }}</li>
    </ul>
    <h3>遍歷li的值</h3>
    {% for item in li %}
        <p>{{ item }}</p>
    {% endfor %}
    <h3>遍歷列表,去對象的值</h3>
    {% for user in user_list %}
        用戶名:<span>{{ user.name }}</span>
        密碼:<span>{{ user.age }}</span>
    {% endfor %}
    <h3>遍歷字典,</h3>
    {% for user in dic.items %}
        用戶名:<span>{{ user.name }}</span>
        密碼:<span>{{ user.age }}</span>
    {% endfor %}    
    <h3>遍歷列表,去對象的值: 倒序</h3>
    {% for user in user_list reversed %}
        用戶名:<span>{{ user.name }}</span>
        密碼:<span>{{ user.age }}</span>
    {% endfor %}
    </body>
    </html>
    

三、模板語法

1、變量--{}

1.1、 {}語法

  1. 語法格式
    {{ }}
    
  2. 舉個栗子
    #views.py
    def index(request):
      return render(request, 'home/index.html', {'content','模板語法'})
    
    <body>
     <p>{{ content }}</p>
    </body>
    

1.2、語法

  1. 語法格式
    對象.變量名
    
  2. 應用
    字典查詢(Dictionary lookup)
    屬性或方法查詢(Attribute or method lookup)
    數字索引查詢(Numeric index lookup)
    對象.方法名(必須無參)
    
  3. 舉個栗子
    見基本

2、標簽--{% tag %}

標簽看起來像是這樣的: {% tag %}。標簽比變量更加復雜:一些在輸出中創建文本,一些通過循環或邏輯來控制流程,一些加載其后的變量將使用到的額外信息到模版中。

一些標簽需要開始和結束標簽 (例如{% tag %} ...標簽 內容 ... {% endtag %})

2.1、for

  1. 語法格式1
    {% for 元素 in 可迭代對象 %}
        {{ 元素 }}
    {% endfor %}
    {% for 元素 in 可迭代對象 %}
        {{ 元素. 屬性}}
    {% endfor %}
    
  2. 語法格式2
    {% for 元素 in 可迭代對象 reversed%}
        {{ 元素. 屬性}}
    {% endfor %}
    
  3. 語法格式3
    {% for 元素 in 可迭代對象 %}
        <p>{{元素.屬性}}</p>
    {% empty %}
        <p>空元素</p>
    {% endfor %}
    
  4. 語法格式4
    {% for item in 可迭代對象 %}
     # 默認從1開始計數
        {{ forloop.counter }}
        # 表示從0開始計數
        {{ forloop.counter0 }}
        #
        {{ forloop.recounter }}
        {{ forloop.recounter0 }}
        # 判斷是否是第一個元素
        {{ forloop.first }}: {{ item }}
        # 判斷是否是最后一個元素
        {{ forloop.last }}: {{ item }}
    {% endfor %}
    
  5. 示例代碼
    {% for item in li  %}
        <h3>計算器</h3>
        計數默認:<span>{{ forloop.counter0 }}</span>
        計數倒序:<span>{{ forloop.revcounter }}</span>
        是否第一項:<span>{{ forloop.first }}</span>
        是否是最后一項:<span>{{ forloop.last }}</span>
    {% endfor %}
    
    {% for link in links %}
        {{ link }}
        {% if not forloop.last %} | 
        {% endif %}
    {% endfor %}
    

2.2、if

  1. 語法格式
    {% if 條件表達式1 %}
    {% elif 條件表達式2  %}
    {% else %}
    {% endif %}
    
  2. 示例代碼
    {% if num > 100 or num < 0 %}
        <p>無效</p>
    {% elif num > 80 and num < 100 %}
        <p>優秀</p>
    {% else %}
        <p>差</p>
    {% endif %}
    

2.3、csrf_token

  1. 說明
    用于生成csrf_token的標簽,用于防治跨站攻擊驗證。注意如果你在view的index里用的是render_to_response方法,不會生效。其實,這里是會生成一個input標簽,和其他表單標簽一起提交給后臺的。
    注意:在settings中的中間件MIDDLEWARE中配置打開
    'django.middleware.csrf.CsrfViewMiddleware',
  2. 語法格式
    {%csrf_token%}
    
  3. 示例代碼
    <form action="{% url "bieming"%}" >
              <input type="text">
              <input type="submit"value="提交">
              {%csrf_token%}
    </form>
    

2.4、url

  1. 說明
    引用路由配置的地址
  2. 語法格式
    {% url 'name' %}
    
  3. 舉個栗子
    url的用法也很簡單,只要在urlpatterns里使用它,附加一個name
    urlpatterns = [
     url(r'^home$','index' ,name="test_url"),
    ]
    
    <a href="{% url 'test_url' %}"></a>
    

2.5、static

  1. 說明
    引用靜態文件
  2. 使用步驟
    1、在首部使用模板標簽{% load staticfiles %}來說明一下內容,將載入靜態文件;
    2、使用{% static 'css/style.css' %}來指明CSS框架文件的存放位置;
    3、若html文件中,出現需要引用靜態文件的地方,都需要用static來替換。
  3. 示例代碼
    <!DOCTYPE html>
    <html lang="en">
    {% load staticfiles %}
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link href="{% static 'css/common.css'%}" rel='stylesheet'>
        <script src="{% static 'js/jquery-3.3.1.js'%}"></script>
    </head>
    <body>
    </body>
    </html>
    

模板標簽

  1. 說明
    該標簽允許在(模板中)包含其它的模板的內容。 標簽的參數是所要包含的模板名稱,可以是一個變量,也可以是用單/雙引號的字符串。 每當在多個模板中出現相同的代碼時,就應該考慮是否要使用 {% include %} 來減少重復。
  2. 語法
    {% include '引入的模板名' %} 
    
  3. 示例代碼
    top.html
    <div>
        <a href="{% url 'login' %}">請登錄</a>
        <a href="{% url 'register' %}">免費注冊</a>
    </div>
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
     {% include 'top.html' %}
    </body>
    </html>
    

3、過濾器 {{obj|filter__name:param}}

可以通過過濾器來修改變量的顯示,過濾器的形式是:{{ variable | filter }},管道符號'|'代表使用過濾器
過濾器能夠采用鏈式的方式使用,例如:{{ text | escape | linebreaks }}
過濾器還可以帶參數,例如: {{ bio|truncatewords:30 }}
過濾器的參數中如果帶有空格,那么需要用引號引起來,例如:{{ list | join : ", "}}
django中30個內建的過濾器

3.1、add

  1. 說明
    給變量加上相應的值
    過濾器首先會強制把兩個值轉換成Int類型。如果強制轉換失敗, 它會試圖使用各種方式吧兩個值相加。它會使用一些數據類型 (字符串, 列表, 等等.)
  2. 語法格式
     {{ value|add:"值" }} 
    
  3. 舉個栗子
    #st = 'hello'
    {{ st|add:"world" }}
    

3.2、default

  1. 說明
    如果一個變量是False或者為空,使用給定的默認值。否則,使用變量的值
  2. 語法格式
    {{ value|default:",默認值" }}
    
  3. 舉個栗子
    title = ''
    {{ title|default:",默認值" }}
    

3.3、length

  1. 說明
    返回值的長度。它對字符串和列表都起作用
  2. 語法格式
    {{ value|length }}
    
  3. 舉個栗子
    li =  ['a', 'b', 'c', 'd']
    {{ li|length }}  #4
    

3.5、date

  1. 說明
    按指定的格式字符串參數格式化 date 或者 datetime 對象
  2. 語法格式
    {{ value|date:"日期格式" }}
    
  3. 舉個栗子
    #如果 now_time = datetime.datetime.now()
    {{ now_time|date:"Y-m-d H:i:s" }}
    

4、自定過濾器

4.1、說明

在內置的方法滿足不了我們的需求的時候,就需要自己定義屬于自己的方法了,自定義方法分別分為filter和simple_tag

4.2 、區別

  1. 傳參:
    • filter默認最多只支持2個參數:可以用{{value|fun:"p1, p1, p3" }}這種形式將參數傳遞個函數
    • simple_tag支持多個參數:{% fun p1 p2 p3 p4 %} 有多少就寫多少
  2. 模板語言if條件:
  • filter支持if
      # 函數的結果作為if語句的條件
      {% if value|f1 %}   
         <h1>True</h1>
      {% else %}
         <h1>False</h1>
    
  • simple_tag: 不支持模板語言if條件`

4.3、步驟

  1. 在settings中的INSTALLED_APPS,注冊app
  2. 在app中創建templatetags目錄,目錄名必須為templatetags
  3. 創建一個自定義的custom_tags.py
    from django import template
    from django.utils.safestring import mark_safe
    # register的名字是固定的,不可改變
    register = template.Library()
    # 過濾器
    @register.filter
    def test_filter(value, param):
        return value + param
    @register.filter
    def test_filter2(value, param1,param2):
        return value + param1 + param2
    # 標簽
    @register.simple_tag
    def multi_tag(value, p2, p3, p1):
        return value * p2 * p3 * p1
    @register.simple_tag  # 標簽
    def my_input(id, arg):
        result = "<input type='text' id='%s' class='%s' />" % (id, arg,)
        return mark_safe(result)
    
  4. 在使用自定義simple_tag和filter的html文件中導入之前創建的 custom_tags.py
  5. 在引用模板中導入:{% load custom_tags %}
  6. 在模板中使用
    {#  使用filter方式調用自定義方法  #}
    <!-- 將當做參數傳遞給test_filter1函數進行處理    處理方式 test_filter2(test_filter1) -->
    <p>{{ test_filter1|test_filter2}}</p>
    !-- 將test_filter當做參數傳遞給test_filter2函數進行處理,接受2個參數  處理方式
        <p>{{ test_filter1|test_filter2:"xxx" }}</p>
    {#  使用simple_tag方式調用自定義方法  #}
    <!-- 將k1當做參數傳遞給multi_tag函數進行處理,接收多個參數  處理方式 multi_tag("處理的值", "參數1" "參數2" "參數3") -->
    <p>{% multi_tag "處理的值" "參數1" "參數2" "參數3" %}</p>
    

四、模版繼承

1、說明

Django模版引擎中最強大也是最復雜的部分就是模版繼承了。模版繼承可以讓您創建一個基本的“骨架”模版,它包含您網站中的全部元素,并且可以定義能夠被子模版覆蓋的塊

2、相關語法

  1. 繼承語法
    {% extends "母版名稱" %} 
    
  2. 塊語法
    {% block 塊名稱 %}
      重寫內容
    {% endblock %}
    

3、示例代碼

  1. 母版
    <!DOCTYPE html>
    <html lang="en">
    {% load staticfiles %}
    <head>
        <meta charset="UTF-8">
        <title>
            {% block  page_title %}
            {% endblock %}
        </title>
        {% block page_css %}
        {% endblock %}
        {% block page_jq %}
        {% endblock %}
    </head>
    <body>
    <div>
        <div id="head">
            {% block page_head %}
            {% endblock %}
        </div>
        <div id="content">
            {% block page_content %}
            {% endblock %}
        </div>
        <div id="footer">
            {% block page_footer %}
            {% endblock %}
        </div>
    </div>
    </body>
    </html>
    
  2. 子模板
    {% extends 'base.html' %}
    {% block page_jq %}
     jq代碼
    {% endblock %}
    {% block page_head %}
     頭部HTML代碼
    {% endblock %}
    {% block page_content %}
     主體HTML內容代碼
    {% endblock %}
    {% block page_footer %}
     底部HTML內容代碼
    {% endblock %}
    

4、總結

  1. 如果你在模版中使用 {% extends %} 標簽,它必須是模版中的第一個標簽。其他的任何情況下,模版繼承都將無法工作。
  2. 在base模版中設置越多的 {% block %} 標簽越好。請記住,子模版不必定義全部父模版中的blocks,所以,你可以在大多數blocks中填充合理的默認內容,然后,只定義你需要的那一個。多一點鉤子總比少一點好。
  3. 如果你發現你自己在大量的模版中復制內容,那可能意味著你應該把內容移動到父模版中的一個 {% block %} 中。
  4. 如果需要獲取父模板中的block 的內容,可以使用{{ block.super }} 變量。如果你想要在父block 中新增內容而不是完全覆蓋它,它將非常有用。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。