1. 程式人生 > >Django之模板(Template)

Django之模板(Template)

新建 內部 寫法 models else person ret Language 自定義函數

Django模板系統

官方文檔

每一個Web框架都需要一種很便利的方法用於動態生成HTML頁面。 最常見的做法是使用模板。

模板包含所需HTML頁面的靜態部分,以及一些特殊的模版語法,用於將動態內容插入靜態部分。

說白了,模板層就是如何往HTML文件中填入動態內容的系統。

Django可以配置一個或多個模板引擎(語言),也可以不用引擎。

Django自帶一個稱為DTL(Django Template Language )的模板語言,以及另外一種流行的Jinja2語言(需要提前安裝,pip install Jinja2)。

Django為加載和渲染模板定義了一套標準的API,與具體的後臺無關。加載指的是,根據給定的模版名稱找到的模板然後預處理,通常會將它編譯好放在內存中。渲染則表示,使用Context數據對模板插值並返回生成的字符串。

DTL作為Django原生的模板系統,一直到Django1.8,都是唯一的內置模版系統,可能你對它有些意見,但是它仍然是一個優秀的模版庫。如果沒有特別重要的理由,需要選擇另外一種模版系統的話,建議堅持使用DTL,特別是在編寫可插拔的應用並打算發布其模板的時候。Django很多內部組件都使用了DTL,例如django.contrib.admin,如果你不想讓它們罷工,或者花費大力氣進行修改,不要放棄DTL。

配置引擎

模板引擎通過settings中的TEMPLATES設置來配置。這是一個列表,與引擎一一對應,每個元素都是一個引擎配置字典。由startproject命令生成的settings.py

會自定定義如下的值:

常用語法

只需要記兩種特殊符號:

{% %}

變量相關的用{{}},邏輯相關的用{%%}。

變量

{{ 變量名 }}

變量名由字母數字和下劃線組成。

點(.)在模板語言中有特殊的含義,用來獲取對象的相應屬性值。

例子:

技術分享圖片
tenplate_test.html
<body>
{#  變量相關用{{  }} #}
{{ s1 }}
{# helson 字符串#}
<hr>
{{ l }}
{#[‘jassin‘, ‘lishi‘, ‘dandan‘] 列表 #}
{##}
<hr>
{{ d }}
{#{‘name‘: ‘jassin‘, ‘age‘: 21}  字典#}
<hr> {{ l2 }} {#對象列表#} {#[<app01.views.template_test.<locals>.Person object at 0x00000000048DD470>, #} {# <app01.views.template_test.<locals>.Person object at 0x00000000048DD358>, #} {# <app01.views.template_test.<locals>.Person object at 0x00000000048DD4E0>]#} views.py def template_test(request): s1 = "helson" l = ["jassin","lishi","dandan"] d = {"name":"jassin","age":21} class Person(object): def __init__(self,name): self.name = name def dream(self): return "{}的夢想是好好生活".format(self.name) jassin = Person("Jassin") lishi = Person("Lishi") dandan = Person("Dandan") l2 = [jassin,lishi,dandan] # return render(request, "template_test.html",{locals()}) return render(request, "template_test.html",{"s1":s1,"l":l,"d":d,"l2":l2}) urls.py url(r^template_test/$,views.template_test, name="template_test"),
參數

模板支持的寫法

{# 取l中的第一個參數 #}
{{ l.0 }}
{# 取字典中key的值 #}
{{ d.name }}
{# 取對象的name屬性 #}
{{ l2.0.name }}
{# .操作只能調用不帶參數的方法 #}
{{ person_list.0.dream }}

註意點;

Django模板語言 對象.方法就可以執行,不需要加括號

Filters過濾器

語法: {{ value|filter_name:參數 }}

技術分享圖片
html頁面
<body>
{#  變量相關用{{  }} #}
{{ s1 }}
{# helson 字符串#}
<hr>
{{ l }}
{{ l.1 }}
{#[‘jassin‘, ‘lishi‘, ‘dandan‘] 列表 #}
{##}
<hr>
{{ d }}
{{ d.age }}
{#{‘name‘: ‘jassin‘, ‘age‘: 21}  字典#}
<hr>
{{ l2 }}
{{ l2.0.name }}
{{ l2.0.dream }}
<hr>
{{ lili|default:"沒有這個值" }}
{#沒有這個值#}
{{ l|length }}
{# 3#}
{{ filesize|filesizeformat }}
{#1.2 KB#}
{{ s1|slice:"1:3" }}
{#el#}
<hr>
{{ now }}
{#Jan. 19, 2018, 4:37 p.m.#}
<hr>


views。py
def template_test(request):
    s1 = "helson"
    l = ["jassin","lishi","dandan"]
    d = {"name":"jassin","age":21}

    import datetime
    now = datetime.datetime.now()




    class Person(object):
        def __init__(self,name):
            self.name = name

        def dream(self):
            return "{}的夢想是好好生活".format(self.name)

    jassin = Person("Jassin")
    lishi = Person("Lishi")
    dandan = Person("Dandan")

    l2 = [jassin,lishi,dandan]

    # return render(request, "template_test.html",{locals()})
    return render(request, "template_test.html",{"s1":s1,"l":l,"d":d,"l2":l2,"filesize":1200,"now":now})
參數

default

{{ value|default: "nothing"}}  如果value值沒傳的話就顯示nothing
{{ lili|default:"沒有這個值" }}

length

返回value的長度,如 value=[‘a‘, ‘b‘, ‘c‘, ‘d‘]的話,就顯示4.
l = ["jassin","lishi","dandan"] {{ l|length }} # 3

filesizeformat

將值格式化為一個 “人類可讀的” 文件尺寸 (例如 ‘13 KB‘, ‘4.1 MB‘, ‘102 bytes‘, 等等)。

例如:(自動轉化)

"filesize":1200
{{ filesize|filesizeformat }}
# 1.2 KB

slice切片

s1 = "helson"
{{ s1|slice:"1:3" }}  # 左包含右不包含
# el

date格式化

{{ now|date:"Y-m-d  H:i:s" }}
2018-01-19 16:41:42

safe**

Django的模板中會對HTML標簽和JS等語法標簽進行自動轉義,原因顯而易見,這樣是為了安全。但是有的時候我們可能不希望這些HTML元素被轉義,比如我們做一個內容管理系統,後臺添加的文章中是經過修飾的,這些修飾可能是通過一個類似於FCKeditor編輯加註了HTML修飾符的文本,如果自動轉義的話顯示的就是保護HTML標簽的源文件。為了在Django中關閉HTML的自動轉義有兩種方式,如果是一個單獨的變量我們可以通過過濾器“|safe”的方式告訴Django這段代碼是安全的不必轉義。

比如:

value = "<a href=‘#‘>點我</a>"
{{ value|safe}}
{{ s2 }}
{#<a href=‘http://www.jianshu.com/‘>點呀</a> 自動幫你轉譯成字符串#}

truncatechars

如果字符串字符多於指定的字符數量,那麽會被截斷。截斷的字符串將以可翻譯的省略號序列(“...”)結尾。

參數:截斷的字符數

{{ s3 }}
風中的少年如今在他鄉皎潔的月光寂靜的晚上誰的思念伴我入夢鄉。
{{ s3|truncatechars:6 }}  字符   風中的...
{{ s3|truncatewords:3 }}  單詞(用於單詞之間的空格)

自定義filter***

技術分享圖片
template_test.html
{% load app01_tags %}
{{ s1|replace:"o"}}



app01_tags.py
from django import template
register = template.Library()

# {{變量|filter_name:參數}}
# name 是給函數起名字,
@register.filter(name="replace")
def func(value,arg):
    return value.replace(arg,"666")
參數
app01/
    __init__.py
    models.py
    templatetags/  # 在app01下面新建一個package package
        __init__.py
        app01_filters.py  # 建一個存放自定義filter的文件
    views.py

技術分享圖片

編寫自定義filter

from django import template
register = template.Library()


@register.filter(name="cut")
def cut(value, arg):
    return value.replace(arg, "")


@register.filter(name="addSB")
def add_sb(value):
    return "{} SB".format(value)

from django import template
register = template.Library()

# {{變量|filter_name:參數}}
# name 是給函數起名字,
@register.filter(name="replace")
def func(value,arg):
return value.replace(arg,"666")

使用自定義filter

{# 先導入我們自定義filter那個文件 #}
{% load app01_filters %}

{# 使用我們自定義的filter #}
{{ somevariable|cut:"0" }}
{{ d.name|addSB }}

# 將o替換成666
{% load app01_tags %} # 導入
{{ s1|replace:"o"}}
{#hels666n#}

Tags(跟邏輯相關)

for

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% endfor %}
</ul>

for循環可用的一些參數:

技術分享圖片

for ... empty

l4沒有
<ul> {% for name in l4 %} <li>{{ name }}</li> {% empty %} <li>什麽都沒有</li> {% endfor %} </ul>
# 什麽都沒有

if,elif和else

{% if user_list %}
  用戶人數:{{ user_list|length }}
{% elif black_list %}
  黑名單數:{{ black_list|length }}
{% else %}
  沒有用戶
{% endif %}

當然也可以只有if和else.

{% if user_list|length > 5 %}
  七座豪華SUV
{% else %}
    黃包車
{% endif %}

if語句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷。

with

定義一個中間變量

當l2.0.dream變量比較長的可以起個中間變量,別名
{% with l2.0.dream as dream %} {{ dream }} # 這裏可以直接調用那個中間變量 {% endwith %}

csrf_token********

這個標簽用於跨站請求偽造保護。
在頁面的form表單裏面寫上{% csrf_token %}

技術分享圖片

------------------------------------------------模板引擎--------------------------------

模板引擎

a. 基本使用

  {{ k1 }}

  if

  for

自定義函數

b.模板中自定義函數

  在已註冊的app中創建一個名字叫 templatetags 文件夾

  在任意創建一個py文件

  創建名字叫register的Library類的對象

  定義函數

from django.template import Library
register = Library() 

   # 調用示例:{{"jassin"|func1:"jassin,lili"}}
   # 參數最多2
   # 可以做if的
@register.filter
def meikai(a1,a2):
n1,n2 = a2.split(‘,‘)
data = "我的名字叫:%s,我喜歡%s和%s" %(a1,n1,n2)
return data
   

   # 調用示例:{% func3 1 2 3 4 %}
   # 參數無限制
   # 無法做if條件
   @register.simple_tag
   def func3(a1,a2,a3,a4):
      resule = a1+a2+a3+a4
      return result
  使用
    {% load xl %}
{{ "jassin"|meikai:"lishi,lili"}}
{% func2 1 2 3 4 %}

# 關於自己建app
  註冊app
  推薦:‘app01.apps.App01Config‘

技術分享圖片

模板引擎示例:

技術分享圖片
{% load xl %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <h1>{{ k1 }}</h1>
    <h1>{{ k1|upper }}</h1>    {# 使字母大寫 #}
    <h1>{{ "jassin"|func1:"lishi,lili"}}</h1>
    <h1>{% func2 1 2 3 4 %}</h1>

    {% if "sudflexsdf"|func3 %}
        <h1>哇哈哈哈</h1>
    {% else %}
        <h1>娃哈哈</h1>
    {% endif %}

{#這也是能使字母大寫的方法,但不是動態的#}
{#    {% if k1 == ‘v1‘ %}#}
{#        <h1>V1</h1>#}
{#    {% endif %}#}



</body>
</html>
HTML
# templatetags文件
from
django.template import Library register = Library() def func1(a1,a2): n1,n2 = a2.split(,) data = "我的名字叫:%s,我喜歡%s和%s" %(a1,n1,n2) return data # 接收多個參數,但不能做if條件 @register.simple_tag def func2(a1,a2,a3,a4): result = a1+a2+a3+a4 return result # 只能接收2個參數,可以做if條件 @register.filter def func3(a1): if alex in a1: return True return False @register.filter def func4(a1): if alex in a1: return True return False

Django之模板(Template)