Templates

  • 配置
    有關模板的配置位于settings.py中的TEMPLATES中
    # settings.py
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
           # 'DIRS' 定義一個Django在查找模板時應該遍歷的目錄列表
            'DIRS': [],
            # 'APP_DIRS' 指明Django是否應該去各app應用目錄下查找模板
            'APP_DIRS': True,
            'OPTIONS': {
                # ... some options here ...
            },
        },
    ]
    

  • 使用模板(django.template.loader)
    • get_template(template_name, using=None)
      返回查找到的模板對象
    • select_template(template_name_list, using=None)
      同get_template()用法一致,只不過返回的是模板對象列表(因為參數也是列表)
    • exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)
      當模板未能找到時,引發該異常
    • exception TemplateSyntaxError(msg)
      當被查找到的模板中存在語法錯誤時引發該異常
    • render(context=None, request=None)
      查找到并返回的Template對象必須實現上邊的方法
    • render_to_string(template_name, context=None, request=None, using=None)
      get_template()函數和render()方法的結合

模板語言

  • 模板變量({{ variables }})

    當模板系統遇到一個 '.' 時,將會按照以下順序進行查詢

    • 查詢相應的字典
    • 查詢屬性或者方法
    • 查詢序列索引

    如果查詢的結果可以被調用,Django將會進行無參數調用,并返回調用結果
    若變量不存在,模板系統將會插入string_if_invalid中設置的值(該值在settings.TEMPLATES['OPTIONS']中設置)

  • 過濾器

    • 一般形式:{{ name|lower }}
    • 鏈狀形式:{{ text|escape|linebreaks }}
    • 包含參數:{{ bio|truncatewords:30 }}
    • 含有空格的參數必須使用引號:{{ list|join:", " }}

    Django中所有的過濾器

    • 一些常使用的過濾器
      • default({{ value|default:"nothing" }}):若變量不存在,則返回default中的參數值
      • length:返回變量的長度(適用于字符串和列表)
      • filesizeformat:將數字以文件大小的表示形式返回(即:13 KB8.8 MB等等)
  • 模板標簽({% tags %})

    使用extends標簽需要注意

    • {% extends %}標簽必須是該模板中的第一個標簽
    • {% block %}標簽的使用多多益善
    • 當需要使用父模板中block里邊的內容時,可以通過{{ block.super }}變量來獲得(注意block.super是變量)
    • {% block %}外通過模板標簽創造的變量無法在{% block %}內使用
      {% trans "Title" as title %}
      {% block content %}{{ title }}{% endblock %}
      # 上述標簽將不會返回任何東西
      
    • {% endblock %}中可以選擇性的添加塊名,如{% endblock content %}

Automatic HTML escaping

用戶可能會在變量中添加HTML標簽,而使得模板展示出現錯誤(Cross Site Scripting(XSS)攻擊)
有兩種方法可以避免該問題:

  • 使用escape過濾器將傳入的變量轉變為無害的變量,這種方法是Django默認使用的方法(但是這種方法會escape掉所有傳入的變量)
  • 利用Django的 automatic HTML escaping
關閉自動escape

有時候可能用戶希望傳入原生的HTML語句(即保留標簽的使用等),有以下方法可以使得escape的使用關閉

  • 對于單個變量
    使用save過濾器
    This will be escaped: {{ data }}
    This will not be escaped: {{ data|safe }}
    
  • 對于模板中的塊(blocks)
    使用autoescape標簽
    Auto-escaping is on by default. Hello {{ name }}
    
    # 關閉autoescape(即對傳入變量不做處理)
    {% autoescape off %}
        This will not be auto-escaped: {{ data }}.
    
        Nor this: {{ other_data }}
        {% autoescape on %}
            Auto-escaping applies again: {{ name }}
        {% endautoescape %}
    {% endautoescape %}
    
    autoescape標簽之間中的所有內容(包括其他標簽、子模板等等)都會遵循autoescape的狀態
  • default過濾器
    default過濾器中的內容默認為關閉escape
    # 應該使用這種形式
    {{ data|default:"3 < 2" }}
    # 而不應該使用這種形式
    {{ data|default:"3 < 2"}}
    

自定義標簽和過濾器的使用

  1. 需要確保包含自定義標簽和過濾器的應用在INSTALLED_APPS
  2. 在模板中使用{% load %}標簽
  3. {% load %}標簽可以加載多個庫
    {{ load humanize i18n }}
    

另外需要注意的是,子模板不繼承父模板的{% load %}標簽,因此必要時,需要在子模板中使用{% load %}標簽進行重新加載


Django中內建的標簽和過濾器


自定義標簽和過濾器

布局

  • 在app的直接目錄下創建templatetags文件夾,并將其聲明為一個包(即在templatetags中創建__init__.py文件)
  • temloatetags中創建定義標簽和過濾器的python文件(如poll_extras.py),并在需要用到相應標簽/過濾的模板中通過{% load poll_extras %}引入(注意該app已存在于INSTALLED_APPS
  • 將相關python文件注冊為可以使用的標簽庫
    from django import template
    
    register = template.Library()
    

自定義過濾器

過濾器函數至少需要一個參數(傳入被過濾對象),此外可以選擇性地使用另一個參數

def cut(value, arg):
    return value.replace(arg, '')
# 使用:{{ somevariable|cut:"0" }}
  • 注冊自定義過濾器
    有兩種方法注冊過濾器
    • register.filter()
      # 第一個參數是過濾器使用的名稱,第二個參數是過濾器使用的函數
      register.filter('cut', cut)
      
    • 裝飾器
      # 若裝飾器含有name參數,則該過濾器名稱會被設置為name參數所指對象
      @register.filter(name='cut')
      def cut(value, arg):
          return value.replace(arg, '')
      
      # 若裝飾器沒有name參數,django會自動使用函數名作為過濾器名稱
      @register.filter
      def lower(value):
          return value.lower()
      
  • 強制轉變第一個傳入的參數為字符串類型
    from django import template
    from django.template.defaultfilters import stringfilter
    
    register = template.Library()
    
    @register.filter
    # 該過濾器會將被過濾對象首先轉變為字符串類型
    @stringfilter
    def lower(value):
        return value.lower()
    
  • register.filter()中的其它三個參數(全部默認為False)
    • is_safe
    • needs_autoescape
    • expects_localtime

自定義模板標簽

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容