1. 程式人生 > 實用技巧 >Django學習2

Django學習2

模板渲染

語法 {{ 變數 }}  {% 邏輯 %}

變數

html程式碼:
<!-- 萬能的點 -->
<p>{{ num }}</p>
<p>{{ name }}</p>
<p>{{ namelist.2 }}</p>
<p>{{ d1.age }}</p>
{#<p>{{ a }}</p>  <app01.views.index.<locals>.Animal object at 0x000001F5EA6DD148>#}
<p>{{ a.kind }}</p>   <!-- 檢視物件屬性dog -->
<p>{{ a.eat }}</p>   <!-- 執行物件方法,不用帶括號,所以不能呼叫帶引數的方法 -->
views.py程式碼:
def index(request):
    num = 100
    name = 'shige'
    name_list = ['小智','小霞','小剛']
    d1 = {'name':'小智','age':13,'hobby':'冒險'}

    class Animal:
        def __init__(self):
            self.kind = 'dog'
        def eat(self):
            return 'shit'
    a = Animal()

    return render(request, 'index.html',{'num':num,'name':name,'namelist':name_list,'d1':d1,'a':a})
    return render(request, 'index.html',locals())   # 簡寫,把變數作為鍵,變數的值作為值全部做成一個字典

# locals()的缺點:拿到全部的變數,但工作開發中不一定要用到全部,可能降低效率

過濾器

<!-- 內建過濾器,在前端進行加工 -->
<!-- 獲取資料長度 -->
<p>{{ name_list|length }}</p>

<!-- 預設值,如果一個變數是false或者為空,使用給定的預設值.否則,使用變數的值. -->
<p>{{ xx|default:'nothing!' }}</p>

<!-- filesizeformat 將值格式化為一個“人類可讀的”檔案尺寸 -->
<p>{{ moviesize|filesizeformat }}</p>  <!-- 123123124 -> 117.4 MB -->

<!-- slice 切片 -->
<p>{{ name|slice:':3' }}</p>

<!-- date 日期格式化 Y-m-d H:i:s -->
<p>{{ now|date:'Y-m-d H:i:s' }}</p>   <!-- 2020-08-01 -->

<!-- truncatechars 截斷字元 漢字算一個字元 -->
<p>{{ words|truncatechars:'9' }}</p>  <!-- 'i love you my cat' -> 'i love...' -->

<!-- truncatewords 截斷單詞 -->
<p>{{ words|truncatewords:'3' }}</p>  <!-- 'i love you my cat' -> 'i love you ...' -->

<!-- cut 移除移除變數中所有的與給出的引數相同的字串 -->
<p>{{ words|cut:' ' }}</p>  <!-- 'i love you my cat' -> 'iloveyoumycat' -->

<!-- join 連線字串 -->
<p>{{ name_list|join:'+' }}</p>  <!-- 小智+小霞+小剛 -->

<!-- safe 不必轉義 -->
{#<p>{{ value }}</p>#}
<p>{{ value|safe }}</p>

標籤

1.模板語言的標籤,與html的標籤區分開
2.形式{% tag %}。標籤的作用:在輸出中建立文字,通過迴圈或邏輯來控制流程,載入其後的變數將使用到的額外資訊到模版中。
3.一些標籤需要開始和結束標籤 (例如{% tag %} ...標籤內容 ... {% endtag %})

for 迴圈標籤

迴圈一個字典
{% for key,value in d1.items %}
    <li>{{ key }} --- {{ value }}</li>
{% endfor %}

{% for key,value in d1.items %}
    <li>{{ forloop.counter }}  {{ key }} --> {{ value }}</li>
{% endfor %}

for迴圈其他方法

forloop是迴圈器,通過點來使用功能

forloop.counter            當前迴圈的索引值(從1開始)
forloop.counter0           當前迴圈的索引值(從0開始)
forloop.revcounter         當前迴圈的倒序索引值(從1開始)
forloop.revcounter0        當前迴圈的倒序索引值(從0開始)
forloop.first              當前迴圈是不是第一次迴圈(布林值)
forloop.last               當前迴圈是不是最後一次迴圈(布林值)
forloop.parentloop         本層迴圈的外層迴圈的物件,再通過上面的幾個屬性來顯示外層迴圈的計數等
	forloop.parentloop.counter
	forloop.parentloop.counter0
	......

for empty

for 標籤帶有一個可選的{% empty %} 從句,以便在給出的迴圈主體是空的或者沒有被找到時,可以有所操作。

{% for animal in animal_list %}
    <p>{{ animal.name }}</p>
{% empty %}
    <p>sorry,nothing here</p>
{% endfor %}

if

{% if %}會對一個變數求值,如果它的值是“True”(存在、不為空、且不是boolean型別的false值),對應的內容塊會輸出。

{% if num > 100 or num < 0 %}
    <p>無效</p>
{% elif num > 80 and num < 100 %}
    <p>優秀</p>
{% else %}
    <p>繼續努力</p>
{% endif %}

注意的點:
1.不滿足條件的,不會生成對應的標籤,如num=101,則<p>優秀</p>,<p>繼續努力</p>不會生成.
2.不同於python的if-elif-else結構,elif和else都是寫在if結構裡的.
3.if語句支援 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判斷,注意條件兩邊都有空格.
4.不支援連續判斷,如{% if a > b > c %}...{% endif %}.

with

給複雜的變數起別名
方式一:
{% with total=class23.students.count %}
    {{ total }}
{% endwith %}

方式二:
{% with class23.students.count as total %}
    {{ total }}
{% endwith %}

注意的點:
1. 命名只能在with語句體內用.
2.等號左右不要加空格!

csrf_token

安全認證機制

<form action="" method="post">
    {% csrf_token %}
    使用者名稱: <input type="text" name="username">
    <button>提交</button>
</form>

# csrf_token相當於伺服器給使用者返回html頁面時蓋上了一個戳,等使用者再次提交post資料過來的時候,伺服器會先檢查是否有這個戳,如果有再處理使用者資料並作後續處理.就是一種防禦機制,來判斷使用者提交過來的資料是不是按照伺服器正常給使用者的html頁面裡輸入的.如果非正常則403.

模板繼承

urls.py:
    # 模板繼承
    url(r'^home/', views.home),
    url(r'^menu1/', views.menu1),
    url(r'^menu2/', views.menu2),
    url(r'^menu3/', views.menu3),

views.py:
    # 模板繼承
    def home(request):
        return render(request, 'home.html')
    def menu1(request):
        return render(request,'menu1.html')
    def menu2(request):
        return render(request,'menu2.html')
    def menu3(request):
        return render(request,'menu3.html')
        
templates目錄:
	home.html, menu1.html, menu2.html, menu3.html, base.html(母版,被繼承的模板)
	
母版:寫上共有的部分,並在可能要修改的地方留下鉤子(可以給子版修改的空間),至少留下div css js三個鉤子!
	{% block xxx %} |  {% block css %}  |  {% block js %}
		...			|		...		    |       ...
	{% endblock %}  |  {% endblock %}   |  {% endblock %}

繼承:在需要繼承母版的模板中首先寫上{% extends 'base.html' %},然後在模板留下的鉤子內進行自制化

注意的點:
1.base.html設定越多的 {% block %} 標籤越好.
2.子模板不必全用母版的鉤子,恰當就好.
3.將子頁面的內容和繼承的母版中block裡面的內容同時保留:在鉤子內寫上{{ block.super }}.
4.建議給 {% endblock %} 標籤寫上對應的名字.
5.一個模版中不能定義多個相同名字的block標籤.

元件

urls.py:
    # 元件
    url(r'^nav/', views.nav),
    url(r'^newpro/', views.newpro),

views.py:
    # 元件(搬運)
    def nav(request):
        return render(request,'nav.html')
    def newpro(request):
        return render(request,'newpro.html')
        
templates目錄:
	nav.html, newpro.html
	
newpro.html:
{% include 'nav.html' %}  <!-- 引用nav.html的內容 -->