作者:BerenCamlost
目錄
1 定義模板
1.1 變量
- 視圖傳遞給模板的數據
- 要遵守標識符規則
- 語法
{{var}}
(var代表變量) - 【注意】:如果使用的變量不存在,則插入的是空字符串
- 在模板中使用點語法,點後邊的東西按如下順序進行匹配
- 字典查詢
- 屬性或者方法
- 數字索引
在模板中調用方法
- sunck/models.py:
# 插入到Students類中的方法
def get_name(self):
return self.sname
- sunck/views.py:
# templates 測試
def templates(request):
stu = Students.stuObj2.get(sname='劉德華')
return render(request, 'sunck/templates測試/templates1.html', {'stu': stu})
- sunck/urls.py:
path('template/', views.templates),
- sunck/templates測試/templates.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板測試</title>
</head>
<body>
<h1>{{ stu.get_name }}</h1>
<h1>{{ stu.sname }}</h1>
</body>
</html>
- 效果:
- 【注意】:在模板中調用方法時不能傳遞參數
1.2 標籤
1.2.1 語法
{% tag %}
1.2.2 作用
- 在輸出中創建文本
- 控制邏輯和循環
1.2.3 if
- 格式:
<!--if語句-->
{% if 表達式 %}
語句
{% endif %}
<!--else語句-->
{% if 表達式 %}
語句1
{% else %}
語句2
{% endif %}
<!--else if語句-->
{% if 表達式1 %}
語句1
{% elif 表達式2 %}
語句2
·
·
·
{% elif 表達式n %}
語句n
{% else %}<!--可有可無-->
語句e
{% endif %}
- 舉例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板測試</title>
</head>
<body>
<h1>{{ stu.get_name }}</h1>
<h1>{{ stu.sname }}</h1>
<h1>num={{ num }}</h1>
{% if num is 10 %}
<h2>You are a handsome boy</h2>
{% elif num is 20 %}
<h2>you are a Very handsome boy</h2>
{% else %}
<h2>You are not a handsome boy</h2>
{% endif %}
</body>
</html>
在Views.py中給num傳一個數字,得到效果如下圖所示:
1.2.4 for
{% for 變量 in 列表 %}
{#語句1#}
{% empty %}
{#語句2#}
{% endfor %}
- 【注意】:當列表爲空或者不存在時,執行empty語句,empty可有可無
{{ forloop.counter }}
表示循環次數,可以用在for語句中,例如:
<ul>
{% for student in stu1 %}
{#語句1#}
<li>{{ forloop.counter }}:{{ student.sname }}---{{ student.scontend }}</li>
{% empty %}
{#語句2#}
<li>沒有學生信息</li>
{% endfor %}
</ul>
- views.py文件中爲:
def templates(request):
stu1 = Students.stuObj2.all()
# stu1 = Students.stuObj2.filter(sname__startswith="劉")
# stu1 = Students.stuObj2.filter(sname__startswith="Liu")
return render(request, 'sunck/templates測試/templates1.html', { 'stu1': stu1})
1.2.5 comment
- 格式
{% commnet %}
被註釋的內容
{% endcomment %}
- 作用:相當於多行註釋,被註釋的內容不再執行
1.2.6 ifequal/ifnotequal
- 【作用】:判斷是否相等或者不相等
- 【格式】:
{% ifequal 值1 值2 %}
語句1
{% endifequal %} # 如果值1等於值2,執行語句1,否則不執行語句1
1.2.7 include
- 【作用】:加載模板並以標籤內的參數渲染
- 【格式】:
{% include '模板目錄' 參數1 參數2 %}
1.2.8 url
- 【作用】:反射解析
- 【格式】:
{% url 'namespace: name' p1 p2 %}
1.2.9 csrf_token
- 【作用】:用於跨站請求僞造保護
- 【格式】:
{% csrf_token %}
1.2.10 block, extends
- 【作用】:用於模板的繼承
1.2.11 autoescape
- 【作用】:用於HTML轉義
1.3 過濾器
- 【語法】:
{{var|過濾器}}
- 【作用】:在變量被顯示前修改它,只是加一個效果,對變量不會造成影響
1.3.1 upper/lower
- 大寫和小寫,示例:
{#5. 過濾器#}
<h1>原型:{{ str }}</h1>
<h1>upper:{{ str|upper }}</h1>
<h1>lower:{{ str|lower}}</h1>
- 【效果】:
1.3.2 過濾器可以傳遞參數
- 下面以
var|join:'str'
爲例解釋傳參的過程:
# templates 測試
def templates(request):
stu1 = Students.stuObj2.all()
return render(request, 'sunck/templates測試/templates1.html', {'stu1': stu1,})
<h2>{{ stu1|join:"--的兒子是-->" }}</h2>
【效果】(涉及隱私我打了馬賽克):
1.3.3 default默認值
- 如果一個變量沒有被提供,或者值爲false,空,我們可以通過 default 語法使用默認值
- 【示例】:
<h2>{{ stu1.sname|default:'啥都麼的' }}</h2>
1.3.4 date
- 【作用】:根據給定格式轉換日期爲字符串
- 【示例】:
{{dateVal|date:'y-m-d'}}
以年月日的形式顯示日期,dateVal
是一個日期變量
1.3.5 escape
- 【作用】:HTML轉義
1.3.6 加減乘除
- 【示例】:
<ul>
<li>num:{{ num }}</li>
<li>num+10:{{ num|add:10 }}</li>
<li>num-5:{{ num|add:-5 }}</li>
<!--num/1*5-->
<li>num*5:{% widthratio num 1 5 %}</li>
<li>num/2:{% widthratio num 2 1 %}</li>
</ul>
- 效果:
1.3.7 給之前的學生列表加背景顏色
|divisibleby:2
:可被2整除
<ul>
{% for student in stu1 %}
{% if forloop.counter|divisibleby:2 %}
<li style="background-color: gray">{{ forloop.counter }}:{{ student.sname }}---{{ student.scontend }}</li>
{% else %}
<li style="color: orange">{{ forloop.counter }}:{{ student.sname }}---{{ student.scontend }}</li>
{% endif %}
{% empty %}
<li>沒有學生信息</li>
{% endfor %}
</ul>
- 【效果】(打碼真的費時間):
1.4 註釋
- 【單行註釋】:
{{# #}}
- 【多行註釋】:
{%comment%}....{%endcomment%}
2 反向解析
2.1 作用
即使url變動,也可以根據namespace和name反向解析出正確的域名,從而實現超鏈接的正確執行。
2.2 示例
<a href="{% url 'sunck:good' %}">反解析連接good</a>
# project/project/urls.py
urlpatterns = [
path('sunck/', include('sunck.urls', namespace="sunck")),
]
# project/sunck/urls.py
urlpatterns = [
path('template/good/', views.good, name='good'),
]
2.3 傳入參數
模板:
<a href="{% url 'sunck:good' 1 %}">反解析連接good</a>
url:
path('template/good/<int:id>', views.good, name='good'),
views視圖:
# templates-反向解析 測試
def good(request, id):
return render(request, 'sunck/templates測試/good.html', {'num': id})
good模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>good</title>
</head>
<body>
<h1>good--{{ num }}</h1>
</body>
</html>
3 模板繼承
3.1 作用
- 模板繼承可以減少頁面的重複定義,實現頁面的重用
3.2 block標籤
- 【作用】:在父模板中預留區域 ,子模板去填充
- 【語法】:
{% block 標籤名 %}
...
{% endblock 標籤名 %}
3.3 extends標籤
- 繼承模板,需要寫在模板文件的第一行
- 【語法】:
{% extends 'myApp/base.html(父模板路徑)' %}
{% block 標籤名 %}
內容
{% endblock 標籤名 %}
3.4 示例
- base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>base</title>
</head>
<body>
<div id="header">
<h1>header</h1>
</div>
<div id="main">
{% block main %}
{% endblock main %}
</div>
<div id="footer">
<h1>footer</h1>
</div>
</body>
</html>
- main.html:
{% extends "sunck/模板繼承/base.html" %}
{% block main%}
<h1>{{ 'main'|upper }}</h1>
{% endblock main %}
4 HTML轉義
4.1 問題
# templates 測試
def templates(request):
return render(request, 'sunck/templates測試/templates1.html',
{
'str2': '<h1>HTML轉義</h1>'
})
{#6 HTML轉義#}
{{ str2 }}
- 這時的輸出爲
<h1>HTML轉義</h1>
,未經過渲染,而我們想要的輸出是HTML轉義
4.2 解決
- 過濾器safe可以關閉轉義,escape開啓轉義
- 標籤
{% autoescape off %}...{% endautoescape %}
關閉自動轉義,將off變成on開啓自動轉義
4.3 示例
- html文件:
{#6 HTML轉義#}
{{ str2 }}
{{ str2|escape }}
{{ str2|safe }}
{% autoescape on %}
1{{ str2 }}
2{{ str2 }}
{% endautoescape %}
{% autoescape off %}
1{{ str2 }}
2{{ str2 }}
3{{ str2 }}
{% endautoescape %}
- 【效果】:
5 CSRF
5.1 跨站請求僞造
某些惡意網站包含鏈接,表單,按鈕,js,利用登錄用戶在瀏覽器中認證,從而攻擊服務
5.2 防止CSRF
- 在settings.py文件的
MIDDLEWARE
增加'django.middleware.csrf.CsrfViewMiddleware'
- 上述方法會將所有的跨站請求屏蔽,爲了允許自身的跨站請求服務,應該在HTML頁面中加入
{% csrf_token %}
,如:
<form action="../register/" method="post">
{% csrf_token %}
<!--這裏的action需要和後面的urls路徑相對應-->
姓名:<input type="text" name="name" value=""/>
<hr>
性別:<input type="radio" name="gender" value="1">男<input type="radio" name="gender" value="0">女
<hr>
年齡:<input type="text" name="age" value=""/>
<hr>
愛好:<input type="checkbox" name="hobby" value="power"/>權利<input type="checkbox" name="hobby" value="money">金錢<input type="checkbox" name="hobby" value="beauty">美女<input type="checkbox" name="hobby" value="Tesla">Tesla
<hr>
<input type="submit" value="註冊">
</form>
6 驗證碼
6.1 作用
- 在用戶註冊,登錄頁面的時候使用,爲了防止暴力請求,減輕服務器的壓力
- 是防止CSRF的一種方式
6.2 源碼及效果
- 請查看作者的另外一篇博客:用Python寫一個自動生成簡單驗證碼圖片的程序
6.3 輸入驗證碼
6.3.1 視圖
def verifi_code(request):
return render(request, 'sunck/templates測試/verificationcode.html', )
# 展示結果
def show(request):
code = request.POST.get('code')
right_code = request.session['verification_code']
if code.upper() == right_code.upper():
return HttpResponse('對了!'+right_code)
else:
return HttpResponse('錯了!'+code+'----'+right_code)
6.3.2 url
path('VerificationCode/code', VerificationCode.verification_code),
path('VerificationCode/', VerificationCode.verifi_code),
path('VerificationCode/show', VerificationCode.show, name='show'),
6.3.3 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>驗證碼</title>
</head>
<body>
<h3>請輸入驗證碼</h3>
<form method="post" action="{% url 'sunck:show' %}">
{% csrf_token %}
<input type="text" name="code" value=""/>
<img src="/sunck/VerificationCode/code">
<hr>
<input type="submit" value="登錄"/>
</form>
</body>
</html>