02.Django-模板

Django中模板的用法簡介

1. 模板系統的介紹

Django做爲一個Web框架,其模板所需的HTML輸出靜態部分以及動態內容插入javascript

模板由HTML代碼和邏輯控制代碼構成html

Django框架的模板語言的語法格式:java

{{var_name}}

例如:HTML被直接編碼在python代碼中:python

import datetime
def current_datetie(request):
	time1 = datetime.datetime.now()
	html="<html><body>the time is $s.</body></html>"%time1
	
	return HttpResponse(html)

或者:linux

>>> python manange.py shell		#進入該django項目的環境
>>> from django.template import Context,Template
>>> t1=Template("hello {{name}}.")
>>> c1=Context({"name":"world"})
>>> t1.render(c1)
'hello world.'

同一個模板,能夠有多個上下文,就能夠經過建立模板對象來渲染多個上下文git

建立一個模板就能夠屢次調用render()方法渲染上下文正則表達式

2 模板支持的語法

語法格式:shell

{{var_name}}

Django模板解析工做都是在後臺經過對正則表達式一次性調用來完成django

2.1 深度的變量查找

python manage.py shell  #進入Django項目環境終端

2.1.1 訪問列表索引

>>> from django.template import Template, Context
>>> t1 = Template('hello {{ items.2 }}.')
>>> c1 = Context({'items': ['linux', 'javascript', 'python']})
>>> t1.render(c1)
'hello python.'

2.1.2 訪問字典索引

>>> from django.template import Template,Context
>>> person = {"name":"Jack","age":22}
>>> t1 = Template("{{person.name}} is {{person.age}} years old.")
>>> c1 = Context({"person":person})
>>> t1.render(c1)
'Jack is 22 years old.'

2.1.3 datetime示例

>>> from django.template import Template,Context
>>> import datetime
>>> day1=datetime.datetime.utcnow()
>>> day1.year
2017
>>> day1.month
8
>>> day1.day
20
>>> t1=Template("the month is {{ date.month }} and the year is {{ date.year }}")
>>> c1=Context({"date":day1})
>>> t1.render(c1)
'the month is 8 and the year is 2017'

2.1.4 類的實例

>>> class Person(object):
...     def __init__(self,first_name,second_name):
...             self.first_name=first_name
...             self.second_name=second_name
...
>>> t1=Template("hello,{{ person.first_name }}--{{ person.second_name }}.")
>>> c1=Context({"person":Person("Jack","Bones")})
>>> t1.render(c1)
'hello,Jack--Bones.'

2.1.5 引用對象方法

>>> from django.template import Template,Context
>>> t1 = Template("{{var}}--{{var.upper}}--{{var.isdigit}}")
>>> t1.render(Context({"var":"Hello"}))
'Hello--HELLO--False'
>>> t.render(Context({"var":"666"}))
'666--666--True'

注意點:安全

調用方法時並無使用圓括號,並且也沒法給該方法傳遞參數

2.2 變量的過濾器(filter的使用)

格式:

{{obj|filter:param}}

參數:

add                 給變量加上相應的值
addslashes          給變量中的引號前加上斜線
capfirst			首字母大寫
cut                 從字符串中移除指定的字符
date				格式化日期字符串
default             若是值是False,就替換成設置的默認值,不然就是用原本的值
default_if_none     若是值是None,就替換成設置的默認值,不然就使用原本的值

例子:

#value1="aBcDe"
{{ value1|upper }}#輸入爲"ABCDE"

#value2=5
{{ value2|add:3 }}#輸入爲8

#value3='he  llo wo r ld'
{{ value3|cut:' ' }}#輸入爲"helloworld"

#value4="hello world"
{{ value4|capfirst }}#輸入爲"Hello world"

#import datetime
#value5=datetime.datetime.now()
{{ value5|date:'Y-m-d' }}#輸入爲"2017-08-20"

#value6=[]
{{ value6 }}#輸入爲"[]"
{{ value6|default:'空的' }} #輸入爲"空的"

#value7='<a href="#">click</a>'
{{ value7 }}#輸入爲"<a href="#">click</a>"
{{ value7|safe }}<br> # 若是不想標籤被渲染,加safe便可
{{ value7|striptags }} 

{% autoescape off %}  #Django安全機制關閉,標籤會被渲染
  {{ value7 }}
{% endautoescape %}

#value8='1234'
{{ value8|filesizeformat }}
{{ value8|first }}
{{ value8|length }}
{{ value8|slice:":-1" }}

#value9='http://www.baidu.com/?a=1&b=3'
{{ value9|urlencode }}
value9='hello I am Tony'

標籤(tag)的使用(使用大括號和百分比的組合來表示使用tag)

2.3 模板語言的控制語句

2.3.1 {% if %} 的使用

{% if %}標籤計算一個變量值,若是是「true」,即它存在、不爲空而且不是falseboolean值,

系統則會顯示{% if %}{% endif %}間的全部內容

例子:

{% if num >= 100 and 8 %}
	{% 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 %}

{% if %}標籤接受單個andor或者not來測試多個變量值或者否認一個給定的變量

{% if %}標籤不容許同一標籤裏同時出現andor,不然會產生歧義

例以下面的標籤是不合法的:

{% if obj1 and obj2 or obj3 %}

2.3.2 {% for %}的使用

{% for %}標籤按順序遍歷一個序列中的各個元素,每次循環模板系統都會渲染{% for %}{% endfor %}之間的全部內容

例子:

<ul>
{% for obj in list %}
	<li>{{ obj }}</li>
{% endfor %}
</ul>

能夠在標籤裏添加reversed來反序循環列表:

{% for obj in list reversed %}
...
{% endfor %}

{% for %}標籤能夠嵌套:

{% for country in countries %}
	<h1>{{ country.name }}</h1>
	<ul>
	 {% for city in country.city_list %}
		<li>{{ city }}</li>
	 {% endfor %}
	</ul>
{% endfor %}

for循環不支持中斷循環,也不支持continue語句

{% for %}標籤內置了一個forloop模板變量,這個變量含有關於循環的屬性

forloop.counter         表示循環的次數,它從1開始計數
forloop.counter0        相似於forloop.counter,但它是從0開始計數
forloop.revcounter      反向遍歷整個列表,revcounter表示循環的次數,最後一次爲1
forloop.revcounter0     反向遍歷整個列表,revcounter表示循環的次數,最後一次爲0
forloop.first           返回一個布爾值,當第一次循環時值爲True,其他爲False

例子:

{% for item in todo_list %}
	<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

{% for object in objects %}   
	 {% if forloop.first %}
	 	<li class="first">
	 {% else %}
	 	<li>
	 {% endif %}   
	 	{{ object }}</li>  
{% endfor %}

forloop變量只能在循環中獲得,當模板解析器到達{% endfor %}forloop變量就會消失

若是模板context已經包含一個叫forloop的變量,Django會用{% for %}標籤替代它

Django會在for標籤的塊中覆蓋由開發人員定義的forloop變量的值

在其餘非循環的地方,你的forloop變量仍然可用

2.3.3 {% empty %}

用法:

{{li }}
	  {%  for i in li %}
		  <li>{{ forloop.counter0 }}----{{ i }}</li>
	  {% empty %}
		  <li>this is empty!</li>
	  {% endfor %}

2.3.4 {% csrf_token %} csrf_token標籤

用於生成csrf_token的標籤,用於防治跨站攻擊驗證

若是viewindex裏用的是render_to_response方法,則不會生效

其實這裏是生成一個input標籤,與其餘表單標籤一塊兒提交給後臺的

2.3.5 {% url %} #引用路由配置的地址

2.3.6 {% verbatim %} #禁止render

用法:

{% verbatim %}	#hello標籤不會被模板渲染
	{{ hello }}
{% endverbatim %}

2.3.7 {% load %} 加載標籤庫

2.3.8 自定義filter和simply_tag

一、在app中建立templatetags模塊

二、建立任意 .py 文件,如:my_tags.py

from django import template
from django.utils.safestring import mark_safe

register = template.Library()  # register的名字是固定的,不可改變

@register.filter
def custom_filter(x,y):
	return x*y

@register.simple_tag
def custom_simple(x,y,z):
	return x+y+z

三、在使用自定義simple_tag和filter的html文件中導入以前建立的 my_tags.py :{% load my_tags %}

四、使用simple_tag和filter

-------------------------------HTML文件
{% load xxx %}         # 位於首行,xxx表明自定義的文件名
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>
	<h1>Hello {{ user.0 }}</h1>
	
	{{ user.3|custom_filter:8 }}

	{% custom_simple user.3 2 3 %}
</body>
</html>

五、在settings中的INSTALLED_APPS配置當前app,否則django沒法找到自定義的simple_tag

六、filter能夠用在if等語句後,simple_tag不能夠

{% if num|filter_multi:30 > 100 %}
	{{ num|filter_multi:30 }}
{% endif %}

2.4 模板繼承

2.4.1 include(繼承)模板標籤

{% include %}是一個內建模板標籤,容許在模板中包含其它的模板內容.

標籤的參數是所要包含的模板的名稱,能夠是一個變量,也能夠是單/雙引號硬編碼的字符串.

每當在多個模板中出現相同的代碼時,就應該考慮是否要使用{% include %}來減小代碼重複

2.4.2 extend(繼承)模板標籤

在一個大型網站中,有一些區域的內容始終是不變的,

減小共用頁面區域所引發的重複和冗餘代碼Django框架中使用的方法就是模板繼承

本質上來講,模板繼承是先構造一個基礎框架模板,然後在其子模板中對公用部分和定義塊進行重載

母板:{% block title %}{% endblock %}    # 定義盒子
子板:{% extends "base.html" %}          # 繼承母板的內容,且必須放在模板第一行
   {% block title %}{% endblock %}    # 能夠對盒子的內容進行修改
	  {% csrf_token %}                   # 取消csrf安全保護
   {% black.super %}
	 {% include '小組件路徑' %}           # HTML出現相同塊代碼時,新建公用小組件HTML文件

若是在模板中使用{% extends %},必須保證其爲模板中的第一個模板標記,不然模板不會起做用

通常來講,基礎模板中的{% block %}標籤越多越好,子模板沒必要定義父模板中全部的代碼塊,
所以,能夠用合理的缺省值對一些代碼塊進行填充,而後只對子模板所需的代碼塊進行重定義.

若是多個模板之間的代碼重用太多,能夠考慮將重複代碼段放放到父模板的某個{% block %}中.

當須要訪問父模板中的塊的內容,使用{{ block.super }}標籤,這個魔法變量將會表現出父模板中的內容,

若是隻想在上級代碼塊基礎上添加內容,而不是所有重載,這個魔法變量就很是有用了.

不容許在同一個模板中定義多個同名的{% block %}.

由於block標籤的工做方式是雙向的,block標籤訂義了在父模板中{% block %}.

若是父模板中出現了兩個相同名稱的{% block %}標籤,父模板將沒法使用哪一個塊的內容

相關文章
相關標籤/搜索