Django 模板
阿新 • • 發佈:2018-04-01
大括號 ice OS 百分比 參數 lis shell .html gpo 2.1 變量格式:
1. 模板的組成
- HTML代碼+邏輯控制代碼
2. 邏輯控制代碼的組成
2.1 變量格式: {{var_name}}
# 示例: Template 和 Context 對象 # Terminal python manage.py shell # 進入該django項目的環境 from django.template import Context, Template t = Template('My name is {{ name }}') c = Context({'name':'xiaohu'}) t.render(c) # 同一模板,多個上下文,一旦有了模板對象,就可以通過它渲染多個context,無論何時我們都可以像這樣 # 使用同一模板源渲染多個 context,只進行一次模板創建,然後多次調用 render()方法渲染會更為高效: # 低效: from name in ('小虎','小豬','旺仔'): t = Template('Hello, {{ name }}') print t.render(Context({'name': name})) # 推薦 t = Template('Hello, {{ name }}') from name in ('小虎','小豬','旺仔'): print t.render(Context({'name': name}))
2.2 萬能的句點號
- 到目前為止,我們通過context傳遞的簡單參數值主要是字符串,然而,模板系統能夠非常簡潔地處理更加復雜的數據
結構,例如list
,dictionary
和自定義的對象。 - 在Django模板中遍歷復雜數據結構的關鍵是句點字符(
.
)
# 以下均在 iTerm 中操作 # 示例一:句點可用於訪問列表索引 from django.template import Template, Context t = Template('I have ate {{ items.2 }}') c = Context({'items': ['apples', 'bananas', 'carrots']}) t.render(c) # 輸出: I have ate carrots # 示例二:通過字典鍵訪問字典的值,可以使用句點 from django.template import Template, Context person = {'name':'xiaohu', 'age':'22'} t = Template('{{ person.name }} is {{ person.age }} years old.') c = Context({'person':person}) t.render(c) # 輸出: xiaohu is 22 years old. # 示例三: 通過句點訪問對象的屬性.例如,Python中 datetime.date 對象有 year, month, day 幾個屬性 from django.template import Template, Context import datetime d = datetime.date(1998, 2, 18) t = Template('The month is {{ date.month }} and the year is {{ date.year }}.') c = Context({'date': d}) t.render(c) # 輸出: The month is 2 and the year is 1998. # 示例四: 通過句點訪問自定義對象的屬性 from django.template import Template, Context class Person(object): def __init__(self, first_name, last_name): self.first_name, self.last_name = first_name, last_name t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.') c = Context({'person': Person('Jhon', 'Smith')}) t.render(c) # 示例五: 通過句點訪問對象的方法 from django.template import Template, Context t = Template('{{ var }} --- {{ var.upper }} -- {{ var.isdigit }}') t.render(Context({'var':'hello'})) # 輸出: hello -- HELLO -- False # 註意: # 這裏調用方法時,並沒有使用圓括號,而且也無法給該方法傳遞參數;只能調用不需要參數的方法;
2.3 變量的過濾器(filter)
# 語法格式: {{obj|filter:param}} # param 的值: # add: 給變量加上相應的值; # addslashes: 給變量中的引號前加上斜線; # capfirst: 首字母大寫; # cut: 從字符串中移除指定的字符; # date: 格式化日期字符串; # default: 如果值是False, 就替換成設置的默認值,否則就用本來的值; # default_if_none: 如果值是None,就替換成設置的默認值,否則就用本來的值; # 示例: # value1='aBcDe' {{ value|upper }}<br/> # value2=5 {{ value2|add:3 }}<br/> # value3='he llo wo r ld' {{ value3|cut:' '}}<br/> # import datetime # value4=datetime.datetime.now() {{ value4|date:'Y-m-d'}}<br/> # value5=[] {{ value5|default:'空的'}}<br/> #value6='<a href="#">跳轉</a>' {{ value6 }} {% autoescape off %} {{ value6 }} {% endautoescape %} {{ value6|safe }}<br/> {{ value6|striptags }} # value7='1234' {{ value7|filesizeformat }}<br/> {{ value7|first }}<br/> {{ value7|length }}<br/> {{ value7|slice:':-1'}}<br/>
2.4 標簽(tag)的使用(使用大括號和百分比的組合來表示使用tag)
{% tags %}
# 示例一: {% if %}
{% if num >= 100%}
{% if num > 200 %}
<p>num大於200</p>
{% else %}
<p>num大於100小於200</p>
{% endif %}
{% elif num < 100 %}
<p>num 小於100</p>
{% else %}
<p>num 等於100</p>
{% endif %}
# 示例二:{% for %}
<ul>
{% for obj in list %}
<li>{{ obj.name }}</li>
{% endfor %}
</ul>
# 在標簽裏添加reversed,來反序循環列表
{% for obj in list reversed %}
....
{% endfor %}
# 系統不支持中斷循環,也不支持continue語句, {% for %}標簽內置了一個forloop模板變量,
# 這個變量含有一些屬性可以提供一些關於循環的信息;
# forloop.counter 表示循環的次數,它從1開始計數,第一次循環設為1:
{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
# forloop.counter0 類似於forloop.counter, 但它是從0開始計數,第一次循環設為0
# forloop.first 當第一次循環時,值為True:
{% for object in objects %}
{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}
# 示例三: {% csrf_token %}
# 用於生成 csrf_token 標簽,用於防止跨站攻擊驗證;如果在view的index裏用的是 render_to_response 方法,
# 不會生效;
# {% csrf_token %} 其實,這裏生成一個 input 標簽,和其他表單標簽一起提交給後臺;
<form action="{% url 'book' %}">
<input type="text" name="username">
<input type="password" name="pwd">
<input type="submit" value="提交">
{% csrf_token %}
</form>
# 示例四: {% with %} 用更簡單的變量名替換復雜的變量名
{% with total=fhdhdfkldflkdf %}{{ total }}{% endwith %}
# 示例五: {% verbatin %} 原樣輸出
{% verebatim %}
{{ hello }}
{% endverbatim %}
2.5 自定義 simple_tag
# 示例: 自定義filter 和 simple_tag
# Step1: 創建 mysite/templatetags 模塊(名稱固定)
# Step2: 在該文件夾下,創建任意 .py 文件,例如,my_tags.py
# Step3: 編寫自定義代碼 mysite/templatetags/my_tags.py
from django import template
from django.utils.safestring import mark_safe
register = template.Library() # register 的名稱是固定的,不可改變
@register.filter
def fitler_multi(v1, v2):
return v1 * v2
@register.simple_tag
def simple_tag_multi(v1, v2):
return v1 * v2
@register.simple_tag
def my_input(id, arg):
result = "<input type='text' id='%s' class='%s' />" % (id, arg,)
return mark_safe(result)
# Step4: 在html文件中,導入自定義的 my_tags.py
{% load my_tags %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{{ num|filter_multi:2 }}
{% simple_tag_multi 2 5 %}
</body>
</html>
# Step5: 在 settings 中的 INSTALLED_APPS 配置當前項目 mysite
# 註意:
# filter 可以用在 if 等語句後, simple_tag 不可以
{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}
2.6 extend 模板繼承
- 模板繼承:就是先構造一個基礎框架模板,而後在其子模板中對它所包含站點公用部分和定義塊進行重載;
# 示例:
# Step1: 定義基礎模板
# templates/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>
# 子模板的作用就是重載,添加或保留那些塊的內容
# current_datetime.html
{% extends "base.html" %}
{% block title %}The current time{% endblock%}
{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}
# hours_head.html
{% extends "base.html"%}
{% block title %}Future time{% endblock %}
{% block content %}
<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
{% endblock%}
參考資料:
- Python 全棧
- Python 模板
Django 模板