Django框架模板詳解


 

Django模板詳解

 

模板使用

模板基本由兩個部分組成,一是HTML代碼,二是邏輯控制代碼。
邏輯控制的實現又基本由三個部分組成:
1. 變量的使用
{{ person_name }} #使用雙大括號來引用變量
2. tag的使用
{% if ordered_warranty %} #使用大括號和百分號的組成來表示使用Django提供的
template tag
{% for item in item_list %}
<li>{{ item }}</li>
{% endfor %}
3. filter的使用
{{ ship_date|date:"F j, Y" }},ship_date變量傳給data過濾器,data過濾器通過使用
"F j, Y"這幾個參數來格式化日期數據。"|"代表類似Unix命令中的管道操作。
 
Template system不僅僅可以和view進行合作,也可以自己獨立使用。
最基本的使用方法是:
1. 使用模板代碼字符串作為參數,創建一個Template類
2. 創建模板代碼中所需要的上下文Context對象,包含所需要的各個引用參數的值
3. 調用Template.render()方法,把template渲染成一個完整的字符串。
>> > from django import template
>> > t = template.Template( 'My name is {{ name }}.')
>> > c = template.Context({ 'name' : 'Adrian'})
>> > print t.render(c)
>>> My name is Adrian.
 
還可以在template代碼中使用dict索引,然后在context傳入所需要的dict
>> > from django.template import Template, Context
>> > person = { 'name' : 'Sally', 'age' : '43'}
>> > t = Template( '{{ person.name }} is {{ person.age }} years old.')
>> > c = Context({ 'person' : person})
>> > t.render(c)
u 'Sally is 43 years old.'
 
還可以使用函數, 不過只能使用無參數的函數
>> > from django.template import Template, Context
>> > t = Template( '{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>> > t.render(Context({ 'var' : 'hello'}))
u 'hello -- HELLO -- False'
 
還可以使用列表索引,但是item.-1是不被允許的
>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
u'Item 2 is carrots.'
 
以上的使用方法被稱為Dot Lookup方法。
 
使用dot lookup的訪問函數功能時,需要注意的問題:
1. 當在模板代碼中執行的函數拋出異常時,會一直向上層傳播,除非這個異常中有一個參數
silent_variable_failure=True; 這樣的話,這個出錯的函數信息就會被渲染成空字符串。
>> > class SilentAssertionError( AssertionError) :
... silent_variable_failure = True
>> > class PersonClass4 :
... def first_name( self) :
... raise SilentAssertionError
>> > p = PersonClass4()
>> > t.render(Context({ "person" : p}))
u 'My name is .'
 
2. 很明顯,調用函數會產生一些不好的結果,安全漏洞之類的,如果你有一個BankAccout,
然后在模板中寫成{{ account.delete }}, 這樣在渲染的時候,你的賬號就被刪除了。。。。
所以要在修改一下你的delete函數
def delete(self):
# Delete the account
delete.alters_data = True#縮進沒有問題,把delete看成一個對象,設置它的alters_data屬性。
這樣在渲染的時候,就會變成failed silent。
 
當在渲染的時候,簡單的key值沒有找到時,會failed silent,變成空字符串,而不是大動干戈的
報錯。
>>> from django.template import Template, Context
>>> t = Template('Your name is {{ name }}.')
>>> t.render(Context())
u'Your name is .'
>>> t.render(Context({'var': 'hello'}))
u'Your name is .'
 
Context對象也可以進行增刪改值的操作。
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> c['newvariable'] = 'hello'
>>> del c['foo']
>>> c['foo']
 
使用python manage.py shell啟動python交互式命令行窗口與一般直接啟動python自帶的
交互式命令行窗口的區別是前者會通過找一個DJANGO_SETTINGS_MODULE環境變量,
告訴Django導入settings.py的配置信息。
 

基本的tag和filter的用法

tag:
  • {% if %}的使用
可以使用and, or, not來組織你的邏輯。 但不允許and和or同時出現的條件語句中。
沒有{% elif %}這樣的用法,只能用嵌套來實現多重if語句。
{% if athlete_list %}
<p>Here are the athletes: {{ athlete_list }}.</p>
{% else %}
<p>No athletes are available.</p>
{% if not coach_list %}
<p>Here are the coaches: {{ coach_list }}.</p>
{% endif %}
{% endif %}
  • {% for %} 的使用
用來循環一個list,還可以使用 resersed關鍵字來進行倒序遍歷,一般可以用if語句來先
判斷一下列表是否為空,再進行遍歷;還可以使用 empty關鍵字來進行為空時候的跳轉。
{% for athlete in athlete_list resersed %}
<li>{{ athlete.name }}</li>
{% empty %}
<p>There are no athletes. Only computer programmers.</p>
{% endfor %}
 
for tag還提供了一些內置參數來提供模板循環的信息。
1. forloop.counter 當前循環計數,從1開始
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
2. forloop.counter0 當前循環計數,從0開始,標准索引方式
3. forloop.revcounter 當前循環的倒數計數,從列表長度開始
4. forloop.revcounter0 當前循環的倒數計數,從列表長度減1開始,標准
5. forloop.first bool值,判斷是不是循環的第一個元素
6. forloop.last 同上,判斷是不是循環的最后一個元素
7. forloop.parentloop 用在嵌套循環中,得到parent循環的引用,然后可以使用以上的參數
{% for country in countries %}
<table>
{% for city in country.city_list %}
<tr>
<td>Country #{{ forloop.parentloop.counter }}</td>
<td>City #{{ forloop.counter }}</td>
<td>{{ city }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
  • ifequal和ifnotequal,一看就是直接比較值的tag,需要兩個參數,用法比較有限,
  • 只限於字符串,整數,小數的比較,什么列表,字典,元組不支持。
{% ifequal user currentuser %}
<h1>Welcome!</h1>
{% ifequal section "community" %}
<h1>Community</h1>
{% endifequal %}
{% endifequal %}
  • {# #},模板中注釋的用法,只能用在一行
  • 如果要使用多行注釋,要使用{% comment %}
{# This is a comment #}
{% comment %}
This is a
multi-line comment.
{% endcomment %}
filter:
filter用於變量在顯示之前的一些簡單的處理。使用類似管道的操作符"|",也可以進行鏈式操作
{{ name|lower }}
{{ my_list|first|upper }}
{{ bio|truncatewords:"30" }}
介紹幾個重要的filter:
  • addslashes :給任何的反斜線,單引號,雙引號,再加一個反斜線。在文本中含有javascript字符串的時候有用。
  • date :用來對data和datatime對象的字符串信息進行格式化。
  • {{ pub_date|date:"F j, Y" }}
  • length :返回變量的長度。

在view中使用template:

首先在settings.py中配置模板文件的路徑。
TEMPLATE_DIRS = (
'/home/django/mysite/templates',
)
記住一個路徑的時候要使用逗號,這樣是來區分是一個tuple還是一個block expression
也可以在設置的時候使用python文件路徑操作代碼:
import os.path
 
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)
 
然后,可以在view中使用模板
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime

def current_datetime(request) :
now = datetime.datetime.now()
t = get_template( 'current_datetime.html')
html = t.render(Context({ 'current_date' : now}))
return HttpResponse(html)
 
大多數情況下,你會使用一種shortcut方法, render_to_response()去完成以上的工作。
from django.shortcuts import render_to_response
import datetime

def current_datetime(request) :
now = datetime.datetime.now()
return render_to_response( 'current_datetime.html', { 'current_date' : now})
 
locals()的小技巧
如果你有很多變量要傳給render,一個一個構造dict元素很麻煩。直接把變量名改成模板中所需要的變量名,
再使用locasl()函數,輕松搞定
def current_datetime(request) :
current_date = datetime.datetime.now()
return render_to_response( 'current_datetime.html', locals())
locals()會返回局部空間中變量信息的dict,直接可以傳給render,但有一點需要注意,它會返回把有的局部變量
信息,有一些可能不需要用到,如request變量。
 
{% include %}的使用
{% include 'nav.html' %},用來引入其它模板的內容,減少重復的模板代碼
{% include template_name %},還可以使用變量名
如果include的模板文件沒有找到,當DEBUG為真時,會報錯TemplateDoesNotExist,當為假時,頁面那一塊為
空白。
 
誠然,include可以有效減少模板的重復代碼。但一種更優雅的方式是:
template inheritance.
首先,創建base.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>My helpful timestamp site</h1>
{% block content %}{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
</body>
</html>
 
我們使用一個新的tag,{% block %}用來告訴template engine,這個部分會被子模板
來實現。 如果子模板沒有實現這些部分,就會默認使用父模板的代碼。
 
再看看,子模板要怎么寫:
{% extends "base.html" %}
 
{% block title %}The current time{% endblock %}
 
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
只需要先使用 {% extends %}繼承父模板,再把相應需要實現的部分寫上所需要的內容。
 
{% extends template_name %}也可以使用變量名來實現動態。
模板繼承的三層繼承策略:
1. 創建一個base.html,用來設置外觀
2. 為網站的每一個部分,創建base_SECTION.html,比如base_phote.html, base_forum.html
3. 為每一個頁面創建自己的模板。
 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM