1. 程式人生 > >Django 模板

Django 模板

大括號 ice OS 百分比 參數 lis shell .html gpo

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 模板