[TOC]css
""" Django模板語言 Django的模板語言旨在在功能和易用性之間取得平衡。它讓那些習慣使用HTML的人感到舒服。 若是您對其餘基於文本的模板語言(如Smarty 或Jinja2)有過接觸,那麼您應該對Django的模板感到賓至如歸。 哲學 若是您有編程背景,或者習慣於將編程代碼直接混合到HTML中的語言,那麼您須要記住, Django模板系統不只僅是嵌入到HTML中的Python。這是一種設計,模板系統用於表達,而不是程序邏輯。 Django模板系統提供的標籤功能相似於一些編程結構 如 if,布爾,for標籤,循環標籤等 - 但這些標籤不是簡單地做爲相應的Python代碼執行, 模板系統不會執行任意Python表達式。默認狀況下,僅支持下面列出的標記,過濾器和語法(您能夠根據須要將本身的擴展添加到模板語言中)。 哲學 爲何使用基於文本的模板而不是基於XML的模板(如Zope的TAL)?咱們但願Django的模板語言不只可用於XML / HTML模板。 在World Online,咱們將其用於電子郵件,JavaScript和CSV。您能夠將模板語言用於任何基於文本的格式。 哦,還有一件事:讓人類編輯XML是虐待狂! """
模板只是一個文本文件。它能夠生成任何基於文本的格式(HTML,XML,CSV等)。 模板包含變量,這些變量在評估模板時將替換爲值,而變量則包含控制模板邏輯的標記。 只要是在html裏面有模板語法就不是html文件了,這樣的文件就叫作模板。
模板語句的註釋 {#{{ '10'|add_str:'5 '}}#} {#註釋內容#}
#views 文件函數 def template_test(request): name = '鋼蛋' age = 18 hobby = ['唱', '跳', 'rap', '籃球'] lis = [] st = '' dic = { 'name': '鐵蛋', 'age': 16, 'hobby': hobby, 'keys': 'xxxxx' } dic_2 = {} return render(request,'template_test.html', {'name':name_p,'age':age,'hobby':hobby,'lis':lis,'st':st,'dic':dic,'dic_2':dic_2}) # 模板文件html頁面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>郭楷豐</title> </head> <body> {{ 啦啦啦啦啦 }} <p> {{ name }} </p> <p> {{ age }} </p> <p> {{ hobby }} </p> <p> {{ lis }} </p> <p> {{ st }} </p> <p> {{ dic }} </p> <p> {{ dic_2 }} </p> </body> </html>
#views 文件函數 def template_test(request): lis = [1, 2, 3,4,5] dic = {"name": "黑蛋"} class Person(object): def __init__(self, name, age): self.name = name self.age = age def dream(self): return " 我 is {} age {}歲...".format(self.name,self.age) gangdan = Person(name="鋼蛋", age=18) goudan = Person(name="狗蛋", age=17) tiedan = Person(name="鐵蛋", age=16) person_list = [gangdan, goudan, tiedan] return render(request, "template_test.html", {"lis": lis, "dic": dic, "person_list": person_list}) # 模板文件html頁面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>郭楷豐</title> </head> <boby> <p>{{ lis.0 }}</p> <!--取l中的第一個參數--> <p>{{ dic.name }}</p><!--取字典中key的值--> <p>{{ person_list.0.name }}</p><!--取對象的name屬性--> <p>{{ person_list.0.dream }}</p><!--.操做只能調用不帶參數的方法--> </boby> </html>
#注:當模板系統遇到一個(.)時,會按照以下的順序去查詢: 1. 在字典中查詢 2. 屬性或者方法 3. 數字索引 # 索引不能爲負數
{% for foo in lis %} <!--for循環--> {% if %} <!--if判斷--> {% elif %} <!--elif判斷--> {% endif %} <!--if閉合符--> {% else %} <!--else判斷不成立執行--> {% endfor %} <!--for循環閉合符--> <!--應用 模板html代碼--> <form action="" method="post"> <label for="inputEmail3" class="col-sm-2 control-label">書名: </label> <div class="col-sm-8"> <input type="text" name="book_name" class="form-control" value="{{ edit_obj.title }}"> <select name="pub_id" id="" class="btn btn-default btn-sm"> {% for foo in publishers %} {% if foo == edit_obj.pub %} <option selected value="{{ foo.pk }}"> {{ foo.name }}</option> {% else %} <option value="{{ foo.pk }}"> {{ foo.name }}</option> {% endif %} {% endfor %} </select> </div> <div class="text-center text-danger">{{ error }}</div> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">提交</button> </div> </form> <!--應用 python邏輯代碼 #views 文件函數--> def edit_book(request): error = '' pk = request.GET.get('pk') edit_obj = models.Book.objects.filter(id=pk) if not edit_obj: return HttpResponse('要編輯的數據不存在') if request.method == 'POST': book_name = request.POST.get('book_name') if not book_name.strip(): error = "書名不能爲空" pub_id = request.POST.get('pub_id') if edit_obj[0].title == book_name and edit_obj[0].pub_id == int(pub_id): error = "未做修改" if not error: obj = edit_obj[0] obj.title = book_name obj.pub_id = int(pub_id) obj.save() return redirect('/book_list/') publishers = models.Publisher.objects.all() return render(request,'edit_book.html',{'edit_obj':edit_obj[0],'publishers':publishers,'error':error})
js,python,模板語言的判斷邏輯html
#python 10>5>1 =》 10>5 and 5>1 true #js 10>5>1 =》 10>5 =》 true =》 1>1 false #模板中 不支持連續連續判斷,也不支持算數運算(過濾器)
Django的模板語言不支持連續判斷,也不支持如下寫法:python
{% if a > b > c %} ... {% endif %} #不支持算數運算 + - * /
def xx(request): d = {"a": 1, "b": 2, "c": 3, "items": "100"} return render(request, "xx.html", {"data": d})
{{ data.items }} 默認會取d的items key的值。
Variable | Description |
---|---|
forloop.counter |
當前循環的索引值(從1開始) |
forloop.counter0 |
當前循環的索引值(從0開始) |
forloop.revcounter |
當前循環的倒序索引值(到1結束) |
forloop.revcounter0 |
當前循環的倒序索引值(到0結束) |
forloop.first |
當前循環是否是第一次循環(布爾值) |
forloop.last |
當前循環是否是最後一次循環(布爾值) |
forloop.parentloop |
本層循環的外層循環 |
#for 標籤帶有一個可選的{% empty %} 從句,以便在給出的組是空的或者沒有被找到時,能夠有所操做。 {% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <p>sorry,no person here</p> {% endfor %}
用來修改變量的顯示結果, 語法: {{ value|filter_name:參數 }} ':' 左右沒有空格沒有空格沒有空格web
#寫法一 {% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %} #寫法二 {% with business.employees.count as total %} {{ total }} employee{{ total|pluralize }} {% endwith %}
{{ value|default:"nothing"}} 若是value值沒傳的話就顯示nothing 注:TEMPLATES的OPTIONS能夠增長一個選項:string_if_invalid:'找不到',能夠替代default的的做用。 (在配置文件settings.py設置)
{{ value|filesizeformat }} 若是 value 是 123456789,輸出將會是 117.7 MB
{{ value|add:"2" }} value是數字4,則輸出結果爲6 {{ value|add:"hello" }} value是數字666,則輸出結果爲666hello {{ first|add:second }} 若是first是 [1,.2,3] ,second是 [4,5,6] ,那輸出結果是 [1,2,3,4,5,6]
{{ value|lower }}
{{ value|upper}}
{{ value|title }}
"{{ value|ljust:"10" }}"
"{{ value|rjust:"10" }}"
"{{ value|center:"15" }}"
{{ value|length }} 返回value的長度,如 value=['a', 'b', 'c', 'd']的話,就顯示4.
{{value|slice:"2:-1"}}
{{ value|first }}
{{ value|last }}
{{ value|join:" // " }}
{{ value|cut:' ' }}
#參數:截斷的字符數 {{ value|truncatechars:9}} truncatewords 按照單詞進行截斷, 只針對英文(...)不計數,中文按字計算
#後端 import datetime def mul(request): value = datetime.datetime.now() return render(request, 'mul.html',{'value':value}) #模板語句 {{ value|date:"Y-m-d H:i:s"}} #顯示格式 年-月-日 時:分:秒 #後端 import datetime def mul(request): now = datetime.datetime.now() return render(request, 'mul.html',{'now':now}) #模板直接使用變量 {{ now }} #顯示格式 June 19,2019,22:00 p.m. #時間格式和默認值一塊兒使用 {{ obj.next_date|date:"Y-m-d"|default:"暫無" }}
#settings.py文件設置 USE_L10N = False #更換爲False DATETIME_FORMAT = 'Y-m-d H:i:s' #添加 #也能夠日期與時間分開設置 根據本身的需求設置 DATE_FORMAT = 'Y-m-d' TIME_FORMAT = 'H:i:s'
XSS攻擊全稱跨站腳本攻擊,是爲不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆, 故將跨站腳本攻擊縮寫爲XSS,XSS是一種在web應用中的計算機安全漏洞,它容許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。 XSS是一種常常出如今web應用中的計算機安全漏洞,它容許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。 好比這些代碼包括HTML代碼和客戶端腳本。攻擊者利用XSS漏洞旁路掉訪問控制——例如同源策略(same origin policy)。 這種類型的漏洞因爲被駭客用來編寫危害性更大的網絡釣魚(Phishing)攻擊而變得廣爲人知。對於跨站腳本攻擊, 駭客界共識是:跨站腳本攻擊是新型的「緩衝區溢出攻擊「,而JavaScript是新型的「ShellCode」。
#Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。 可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的, 這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。 爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。
#頁面代碼: {% load my_tags %} {{ 'https://www.baidu.com/'|show:'百度' }} #自定過濾器代碼 @register.filter def show(url,name): return "<a href = '{}'>{}</a>".format(url,name)
#自定過濾器代碼 @register.filter(is_safe = True) def show(url,name): return "<a href = '{}'>{}</a>".format(url,name)
#模板語句 {% load my_tags %} {{ 'https://www.baidu.com/'|show:'百度'|safe }}
頁面效果 django
自定義過濾器是隻能帶有一個或兩個參數的Python函數: 變量(輸入)的值 - -不必定是一個字符串 參數的值 - 這能夠有一個默認值,或徹底省略 例如,在過濾器{{var | foo:「bar」}}中,過濾器foo將傳遞變量var和參數「bar」。 自定義filter代碼文件擺放位置: app01/ __init__.py models.py templatetags/ # 在app01下面新建一個package package __init__.py app01_filters.py # 建一個存放自定義filter的py文件 views.py
#注意 在settings中的INSTALLED_APPS配置當前app,否則django沒法找到自定義的simple_tag (模塊名只能是templatetags)
from django import template register = template.Library() #固定寫法,不可改變
@register.filter #過濾器 def add_str(value, arg): # 最多有兩個 return '{}-{}'.format(value, arg)
{% load my_tags %} #先導入咱們自定義那個文件 my_tags {{ name|add_str:age }} #參數只能是兩個,一個參數是變量name ,一個是參數是後面的那個參數age
#過濾器函數 @register.filter def multiply1(value,arg): return value * arg #模板語句 {% load my_tags %} <p>{{ 6|multiply1:'6' }}</p> <p>{{ 6|multiply1:6 }}</p> <p>{{ '10'|multiply1:5 }}</p>
#過濾器函數 @register.filter def division(value,arg): return value / arg #模板語句 {% load my_tags %} <p>{{ 6|division:6 }}</p> <p>{{ 6|division:1 }}</p>
#過濾器函數 @register.filter def add(value,arg): return value + arg #能夠這樣寫,可是轉換不了會報錯 int(value) + int(arg) #模板語句 {% load my_tags %} <p>{{ 6|add:6 }}</p> <p>{{ 6|add:0 }}</p> <p>{{ '鋼蛋g'|add:18 }}</p>
#過濾器函數 @register.filter def add(value,arg): return value - arg #模板語句 {% load my_tags %} <p>{{ 6|add:6 }}</p> <p>{{ 6|add:0 }}</p>
與自定義filter相似(也是在python包的templatetags文件下,建立此標籤),只不過接收更靈活的參數。 #simple_tag 代碼 @register.simple_tag(name="plus") def plus(a, b, c): return "{} + {} + {}".format(a, b, c) #使用simple tag 自定義標籤 {% load app01_demo %} {# simple tag #} {% plus "1" "2" "abc" %} #例子 標籤代碼 @register.simple_tag def join_str(*args, **kwargs): return '{} - {} '.format('*'.join(args), '$'.join(kwargs.values())) # 模板 {% load my_tags %} {% join_str '1' '2' '鋼蛋' k1='3' k2='4' %}
#分頁顯示代碼 <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {% for i in num %} <li><a href="#">{{ i }}</a></li> {% endfor %} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> #頁面1 {% load my_tags %} {% page 5 %} #頁面2 {% load my_tags %} {% page 1 %}
自定義過濾器 filter 只能接受兩個參數 調用的時候使用 {{ filter }} 自定義標籤 simpletag 與自定義過濾器區別,能夠接受更多參數,使用標籤引用{{% %} 自定義標籤 inclusion_tag 多用於返回html代碼片斷,使用標籤引用{{% %}
在頁面的form表單裏面寫上{% csrf_token %}
#做用 在配置文件找到靜態文件別名,與文件地址進行拼接,這樣別名改了,也不會影響,靜態文件的導入 {% load static %} <img src="{% static "images/hi.jpg" %}" alt="Hi!" /> #引用JS文件時使用: {% load static %} <script src="{% static "mytest.js" %}"></script> #某個文件多處被用到能夠存爲一個變量 {% load static %} {% static "images/hi.jpg" as myphoto %} <img src="{{ myphoto }}"></img> {% load static %} <link rel="stylesheet" href="{% static '/plugins/bootstrap-3.3.7/css/bootstrap.css' %}"> <link rel="stylesheet" href="{% static '/css/dsb.css' %}"> {% static '/plugins/bootstrap-3.3.7/css/bootstrap.css' %} {% get_static_prefix %} # 獲取別名
普通的HTML頁面 母版頁用於處理html頁面相同部份內容,避免出現冗餘代碼,減小重複html頁面的編寫,提升代碼複用性,方便代碼修改.
#在子頁面中在頁面最上方使用下面的語法來繼承母板。 {% extends '母版文件名.html' %}
經過在母板中使用{% block xxx %}來定義"塊"。 在子頁面中經過定義母板中的block名來對應替換母板中相應的內容。 #定義block {% block 塊名 %} {% endblock %} #還能夠{{% endblock 塊名 %}}來關閉標籤,更加清新 #使用block {% block 塊名 %} #本身的內容 {% endblock %} #母版內容和本身內容都使用 {% block 塊名 %} #本身的內容 {% block.super %} {% endblock %}
注意的點: 1. {% extends 'base.html' %} 寫在第一行 前面不要有內容 有內容會顯示 2. {% extends 'base.html' %} 'base.html' 加上引號 否則當作變量去查找 3. 把要顯示的內容寫在block塊中 4. 定義多個block塊,定義 css js 塊
#做用 能夠將經常使用的頁面內容如導航條,頁尾信息等組件保存在單獨的文件中,而後在須要使用的地方按以下語法導入便可。 #示列 單獨建一個html page <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {% for i in num %} <li><a href="#">{{ i }}</a></li> {% endfor %} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> #別的頁面 引用 {% include 'page.html' %}