Django之模版層

模版層

模板語法符號 {{}} 變量相關 {%%} 邏輯相關css

一.模版語法之傳值

  • python基本數據類型所有支持傳遞給html文件
# views.py
def index(request):
    # python全部的數據類型都支持傳遞給html頁面
    i = 11
    f = 11.11
    str = 'hello world'
    list = [1, 2, 3, 4, 5, 6]
    d = {"username": 'jason', 'password': 123, 'hobby': ['read', {'username': ['jason', 'egon']}]}
    t = (1, 2, 3, 4, 5, 6, 7,)
    se = {1, 2, 3, 4, 5, 6}
    b = True
    ff = False
    
	# python後端傳給前端值的兩種方式
    # 第一種傳值方式
    return render(request, 'index.html', {'i':i, 'f':f, 'str': str })

# 第二種傳值方式
    # 會將當前名稱空間全部的變量名都所有傳遞給html頁面
    return render(request, 'index.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ i }}</p>
<p>{{ f }}</p>
<p>{{ str }}</p>
<p>{{ list }}</p>
<p>{{ d }}</p>
<p>{{ t }}</p>
<p>{{ se }}</p>
<p>{{ b}}</p>
<p>{{ ff }}</p>
</body>

  • python後端函數發送到前端html頁面
def index(request):
    # 寫一個示例函數
    def func():
        print('views')
    return render(request, 'index.html', locals())
<!--這下面帶#號的註釋前端瀏覽器是不展現的,可是html自身的註釋是能夠看到的-->
{#<p>{{ i }}</p>#}
{#<p>{{ f }}</p>#}
{#<p>{{ str }}</p>#}
{#<p>{{ list }}</p>#}
{#<p>{{ d }}</p>#}
{#<p>{{ t }}</p>#}
{#<p>{{ se }}</p>#}
{#<p>{{ b}}</p>#}
{#<p>{{ ff }}</p>#}


<p>{{ func }}</p>

因此,當傳遞函數名的時候,函數名會自動加括號進行執行,展現的只是函數的返回值,若不設置返回值,默認返回Nonehtml

注意:模板語法不支持給函數傳參前端

  • python後端傳遞類給前端html頁面
from django.shortcuts import render

def index(request):
    class MyClass(object):
        def get_self(self):
            return 'from self'
        
        @staticmethod
        def get_func():
            return 'from func'

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

    obj = MyClass()
    return render(request, 'index.html', locals())
<p>{{ MyClass }}</p>
<p>{{ obj }}</p>

<body>
<p>{{ MyClass.get_cls }}</p>
<p>{{ MyClass.get_func }}</p>
<p>{{ MyClass.get_self }}</p>
<p>{{ obj.get_cls }}</p>
<p>{{ obj.get_func}}</p>
<p>{{ obj.get_self}}</p>
</body>
</html>

一樣,傳遞類名給前端html時候的也會加括號執行獲取類的對象,也不支持傳參python

  • 取值方法

django模板語法取值 只有一種操做方式 經過句點符 .jquery

def index(request):  
    d = {"username":'jason','password':123,'hobby':['read',{'username':['jason','egon']}]}
    ")
    return render(request,'index.html',locals())
<p>{{ d.hobby.1.username.1 }}</p>

句能夠經過多個句點符的方式去獲取須要的數據django

二.模版語法之過濾器

  • |length:獲取長度
  • |add:加法運算
  • |default:判斷是否爲空
  • |truncatechars:截取字符(指定數量字符中會包括三個點)
  • |truncatewords:截取單詞(截取指定單詞數目,會額外添加三個點)
  • |filesizeformat:自動計算文件大小(MB,GB等)
  • |slice:切片
  • |date:日期格式化
  • |safe:轉義

過濾器語法:過濾器 |左邊的會當作過濾器的第一個參數 過濾器名右邊的會當作過濾器的第二個參數bootstrap

from django.shortcuts import render
from datetime import datetime
# 該模塊能夠幫助後端直接轉義前端標籤
from django.utils.safestring import mark_safe
# Create your views here.

def index(request):
    # python全部的數據類型都支持傳遞給html頁面
    i = 11
    f = 11.11
    s = 'hello world'
    str = 'hello world'
    list = [1, 2, 3, 4, 5, 6]
    d = {"username": 'jason', 'password': 123, 'hobby': ['read', {'username': ['jason', 'egon']}]}
    t = (1, 2, 3, 4, 5, 6, 7,)
    se = {1, 2, 3, 4, 5, 6}
    b = True
    ff = False
    ff = False
    ss = 'kjasdklas ksd;lk  akjsdkl da  kjda k;lak d k;a dk  ska d'
    sss = '卡時間 凍結 鯊科 技的 卡拉 手動 卡薩 丁卡'
    file_size = 32213213424
    ddd = datetime.now()
    #能夠傳入前端轉義
    res = "<h1>你好啊</h1>"
    # 直接傳是不會被前端識別並展現到瀏覽器中的
    res1 = "<script>alert(123)</script>"
    #能夠直接在後端就進行轉義
    res2 = mark_safe("<h1>你好啊</h1>")
    return render(request, 'index.html', locals())
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ s|length }}</p>
<p>{{ i|add:10 }}</p>  <!--加法運算必須先後都是數字或者字符串-->
<p>{{ b|default:'判斷是否爲空,獲得的是布爾值' }}</p> <!--如有值返回True,沒有值返回|右面的參數-->
<p>{{ s|truncatechars:8 }}</p>
<p>{{ ss|truncatewords:3 }}</p>
<p>{{ file_size|filesizeformat }}</p>
<p>{{ s|slice:'0:3:2' }}</p>
<p>{{ ddd|date:'Y年/m月/d日' }}</p> <!--注意time模塊時間戳不能夠轉換-->
<p>{{ res1 }}</p>  <!--後端標籤語言傳入前端是失效的,防止一些惡意腳本攻擊-->
<p>{{ res|safe }}</p><!--能夠經過safe轉義-->
<p>{{ res2 }}</p><!--也能夠在前端經過from django.utils.safestring import mark_safe中的mark_safe方法-->

</body>
</html>

先後端取消轉義
	前端
		|safe
	後端
		from django.utils.safestring import mark_safe
		mark_safe('<h1>安全滴</h1>')
總結:前端代碼不必定非要在前端頁面寫,能夠在後端寫好傳遞給前端頁面使用
這樣的話 你就能夠利用到後端更加多的邏輯語法

三.模版語法之標籤

  • 前端for循環中forloop參數
{% for foo in list %}
    <p>{{ forloop }}</p>
{% endfor %}

獲得下圖,能夠看到有first,last等方法後端

  • 前端if條件
{% for foo in list %}
    {% if forloop.first %}
        <p>這是第一個值</p>
    {% elif forloop.last %}
        <p>這是第一個值</p>
    {% else %}
        <p>{{ foo }}</p>
    {% endif %}
{% endfor %}

補充:for循環的對象必須是可迭代對象或者不爲空,不然沒法執行,能夠經過empty方法瀏覽器

a = []
{% for foo in a %}
    {% if forloop.first %}
        <p>這是第一個值</p>
    {% elif forloop.last %}
        <p>這是第一個值</p>
    {% else %}
        <p>{{ foo }}</p>
    {% endif %}
    {% empty %}
        <p>for循環的對象內沒有值</p>
{% endfor %}

keys,vlues,items一樣可使用安全

d = {"username": 'jason', 'password': 123, 'hobby': ['read', {'username': ['jason', 'egon']}]}
{% for foo in d.items %}
    <p>鍵值對:{{ foo }}</p>
{% endfor %}

{% for foo in d.keys %}
    <p>key:{{ foo }}</p>
{% endfor %}

{% for foo in d.values %}
    <p>值:{{ foo }}</p>
{% endfor %}

補充:能夠經過with起別名快速獲取值

<p>當一個值獲取的步驟很是繁瑣 可是又須要在不少地方用到 咱們能夠用起別名的方式來簡化代碼</p>
<p>{{ d.hobby.1.username.1 }}</p>

<!--或者經過with起一個別名,就能夠快速調用-->

{% with d.hobby.1.username.1 as ag %}
    <p>{{ ag }}</p>
{% endwith %}

四.自定義過濾器,標籤,inclusion_tag

  • 前戲準備工做
1.在應用名下新建一個名字必須叫templatetags文件夾
	2.在該文件夾內新建一個任意名稱的py文件(eg:mytag)
	3.在該文件內 必須先寫如下兩句代碼
		from django.template import Library		
		register = Library()
# 自定義過濾器的建立和使用

1.在應用名下新建一個名字必須叫templatetags文件夾
2.在該文件夾內新建一個名稱爲mytag.py的文件
mytag.py

from django.template import Library		
register = Library()

# 自定義過濾器,給過濾器起個名字my_sum
@register.filter(name='my_sum')

def index(a, b):
    # 注意此處省略了邏輯校驗
    return a + b


index.html文件中使用過濾器

<p>自定義過濾器的使用</p>
{#先將自定義的過濾器加載過來#}
    
{% load mytag %}
<p>{{ 10|my_sum:90 }}</p>

注意:過濾器最多隻能傳兩個參數,即|左右(若是非要傳多個參數,能夠經過x|name:[1,2,3,4]等方式手動處理)

# 自定義標籤的建立和使用

1.在應用名下新建一個名字必須叫templatetags文件夾
2.在該文件夾內新建一個名稱爲mytag.py的文件
mytag.py

from django.template import Library		
register = Library()

# 自定義標籤
@register.simple_tag(name='my_simpletag')
def newtag(a, b, c, d):
    return '%s?%s?%s?%s'%(a, b, c, d)


index.html文件中使用過濾器

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


# 這裏能夠得出:標籤是{%  %},而且能夠傳多個參數,過濾器是{{}},只能傳兩個參數,而且經過simple_tag建立的標籤不能做爲條件使用for循環和if邏輯語句,而經過filter建立的過濾器就可使用if邏輯語句
# 自定義inclusion_tag的建立和使用

#inclusion_tag的做用:
#    好比在一個html頁面上調用一個inclusion_tag,這個inclusion_tag會調用一個函數並生成一些數據,這些數據會放到一個html頁面上進行渲染,將渲染好的頁面再傳回inclusion_tag的位置(相似於函數的裝飾器,能夠額外添加到某個已經寫好的html頁面


# 第一步:自定義inclusion_tag
@register.inclusion_tag('demo.html',name='my_name')
def index1(n):
    list1 = []
    for i in range(n):
        list1.append(i)
    # 將列表數據傳遞給demo.html
    # 注意用locals傳的時候是傳所有變量
    return locals()
    #或者使用字典的形式是指定參數傳值
    # return {'list':list}

# 第二步,能夠新建一個demo.html文件接收數據(只須要部分能實現功能的代碼就好)
<div>
    {% for foo in list1 %}
        <li>{{ foo }}</li>
    {% endfor %}

</div>


# 第三步:調用inclusion_tag
<p>自定義inclusion_tag的使用</p>
{% load mytag %}
{% my_name 10 %}

五.模版的繼承和導入

  • 繼承
模板的繼承
	某一個頁面大部分區域都是公用的 那這個頁面就能夠做爲模板頁面
	當別人繼承這個頁面以後 如何修改對應的區域
	
	先在模板頁面上經過block實現劃定區域
		{% block content %}	
			模板頁面內容
		{% endblock %}
	
	子頁面中先導入整個模板
		{% extends '模板頁面.html'%}
		修改特定的區域  經過實現劃定好的區域名稱
		{% block content %}
			子頁面內容
		{% endblock %}
	
	一般狀況下 模板頁面頁面應該起碼有三塊區域
		{% block css %}	
			模板頁面內容
		{% endblock %}
		{% block content %}	
			模板頁面內容
		{% endblock %}
		{% block js %}	
			模板頁面內容
		{% endblock %}
	# 模板的block塊越多 可擴展性越高
	
	還支持子頁面調用父頁面對應區域的內容 而且能夠無限次調用
		{{ block.super }}
  • 導入
模板的導入
	將html頁面當作模塊使用 哪裏須要導哪裏  這個html頁面一般都不是完整的 只是一個局部樣式
	{% include 'left.html' %}
相關文章
相關標籤/搜索