視頻鏈接:https://www.bilibili.com/video/BV1vK4y1o7jH
一。模板層 - 變數和標籤#
變數#
- 視圖函數中可以將 Python 變數封裝到 字典 中傳遞到模板上
範例:
def xxx_view(request):
dic = {
"變數1": "值1",
"變數2": "值2",
}
return render(request, 'xxx.html', dic)
- 能傳遞到模板中的 數據類型
str-字符串 int-整型
list-數組 tuple-元組
dict-字典 func-方法
obj-類實例化的對象
- 在模板中使用變數語法
- {{ 變數名 }}
- {{ 變數名.index }}
- {{ 變數名.key }}
- {{ 對象.方法 }}
- {{ 函數名 }}
- 演示:
http://127.0.0.1:8000/test_html_param
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_html', views.test_html)
]
# mysite1/mysite1/views.py
def test_html_param(request):
dic = {}
dic['int'] = 88
dic['str'] = 'peng'
dic['lst'] = ['Tom', 'Jack', 'Lily']
dic['dict'] = {'a':9, 'b':8}
dic['func'] = say_hi
dic['class_obj'] = Dog()
dic['script'] = '<script>alert(1111)</script>'
return render(request, 'test_html_param.html', dic)
def say_hi():
return 'hahaha'
class Dog:
def say(self):
return 'wangwang'
# mysite1/templates/test_html_param.html
<h3>int 是 {{ int|add:"2" }}</h3>
<h3>str 是 {{ str|upper }}</h3>
<h3>lst 是 {{ lst }}</h3>
<h3>lst 是 {{ lst.0 }}</h3>
<h3>dict 是 {{ dict }}</h3>
<h3>dict['a'] 是 {{ dict.a }}</h3>
<h3>function 是 {{ func }}</h3>
<h3>class_obj 是 {{ class_obj.say }}</h3>
<h3>script 是 {{ script|safe }}</h3>
標籤#
模板標籤
- 作用:將一些伺服器端的功能嵌入到模板中,例如流程控制等
- 標籤語法:
{% 標籤 %}
...
{% 結束標籤 %}
if 標籤#
- 語法:
{% if 條件表達式1 %}
...
{% elif 條件表達式2 %}
...
{% elif 條件表達式3 %}
...
{% else %}
...
{% endif %} - 需要有結束標籤
- 注意:
- if 條件表達式裡可以用的運算符 ==, !=, <,> , <=, >=, in, not in, is, is not, not、and、or
- 在 if 標記中使用實際括號是無效的語法。如果需要它們指示優先級,則應使用嵌套的 if 標記。
官方文檔:https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/#if
- 演示:
http://127.0.0.1:8000/test_if_for
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_if_for', views.test_if_for),
]
# mysite1/mysite1/views.py
def test_if_for(request):
dic = {}
dic['x'] = 20
dic['lst'] = ['Tom', 'Jack', 'Lily']
return render(request, 'test_if_for.html', dic)
# mysite1/templates/test_if_for.html
{% if x > 10 %}
今天天氣很好
{% else %}
今天天氣非常好
{% endif %}
<br>
{% for name in lst %}
{% if forloop.first %} &&&&& {% endif %}
<p> {{ forloop.counter }} {{ name }}</p>
{% if forloop.last %} ===== {% endif %}
{% empty %}
當前沒數據
{% endfor %}
-
模板標籤 - if 標籤 - 練習
寫一個簡單的計算器頁面,能夠在伺服器端進行簡單加減乘除計算(需記錄用戶上次填寫狀態、下拉列表選擇狀態)
-
前端參考代碼:
-
演示:
http://127.0.0.1:8000/mycal
# mysite1/mysite1/urls.py urlpatterns = [ ... path('mycal', views.test_mycal), ] # mysite1/mysite1/views.py def test_mycal(request): if request.method == 'GET': return render(request, 'mycal.html') elif request.method == 'POST': #處理計算 x = int(request.POST['x']) y = int(request.POST['y']) op = request.POST['op'] result = 0 if op == 'add': result = x + y elif op == 'sub': result = x - y elif op == 'mul': result = x * y elif op == 'div': result = x / y #dic={'x':x, 'y':y, 'op':op} return render(request, 'mycal.html', locals()) # locals方法-局部變量直接封裝成字典(Python自帶方法) # mysite1/templates/mycal.html <form action='/mycal' method='post'> <input type='text' name="x" value="{{ x }}"> <select name='op'> <option value="add" {% if op == 'add' %}selected{% endif %} > +加</option> # ☆ 記錄op狀態,option selected屬性,使用了if標籤 <option value="sub" {% if op == 'sub' %}selected{% endif %}> -減</option> <option value="mul" {% if op == 'mul' %}selected{% endif %}> *乘</option> <option value="div" {% if op == 'div' %}selected{% endif %}> /除</option> </select> <input type='text' name="y" value="{{ y }}"> = <span>{{ result }}</span> <div><input type="submit" value='開始計算'></div> </form>
-
for 標籤#
-
語法:
{% for 變數 in 可迭代對象 %} ... 循環語句 {% empty %} ... 可迭代對象無數據時填充的語句 {% endfor %}
官方文檔:https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/#for
-
內置變量 - forloop
- 演示:
http://127.0.0.1:8000/test_if_for
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_if_for', views.test_if_for),
]
# mysite1/mysite1/views.py
def test_if_for(request):
dic = {}
dic['lst'] = ['Tom', 'Jack', 'Lily']
return render(request, 'test_if_for.html', dic)
# mysite1/templates/test_if_for.html
{% for name in lst %}
{% if forloop.first %} &&&&& {% endif %}
<p> {{ forloop.counter }} {{ name }}</p>
{% if forloop.last %} ===== {% endif %}
{% empty %}
當前沒數據
{% endfor %}
小節#
- 變數調用 - 點大法
- 標籤語法 {% raw %}{% 標籤 %} {% 結束標籤 %}{% endraw %}
二。模板層 - 過濾器和繼承#
過濾器#
- 定義:在變數輸出時對變數的值進行處理
- 作用:可以通過使用 過濾器 來改變變數的輸出顯示
- 語法:{% raw %}{{變數 | 過濾器 1:' 參數 1' | 過濾器 2:' 參數 2' ...}}{% endraw %}
官方文檔:https://docs.djangoproject.com/zh-hans/2.2/ref/templates/builtins/
- 常用過濾器:
- 演示:
http://127.0.0.1:8000/test_html_param
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('test_html', views.test_html)
]
# mysite1/mysite1/views.py
def test_html_param(request):
dic = {}
dic['int'] = 88
dic['script'] = '<script>alert(1111)</script>'
return render(request, 'test_html_param.html', dic)
def say_hi():
return 'hahaha'
class Dog:
def say(self):
return 'wangwang'
# mysite1/templates/test_html_param.html
<h3>int 是 {{ int|add:"2" }}</h3>
<h3>str 是 {{ str|upper }}</h3>
<h3>script 是 {{ script|safe }}</h3>
繼承#
模板的繼承
如下範例:
-
模板繼承可以使父模板的內容重用,子模板直接繼承父模板的全部內容並可以覆蓋父模板中相應的塊
-
語法 - 父模板中:
- 定義父模板中的 ** 塊 block ** 標籤
- 表示出哪些在子模塊中是允許被修改的
- block 標籤:在父模板中定義,可以在子模板中覆蓋
-
語法 - 子模板中:
-
繼承模板
extends
標籤(寫在模板文件的第一行)例如
{% extends 'base.html' %}
-
子模板 重寫父模板中的內容塊
{% block block_name %} 子模板塊用來覆蓋父模板中 block_name 塊的內容 {% endblock block_name %} - block_name 可寫可不寫
-
-
重寫的覆蓋規則
- 不重寫,將按照父模板中的效果顯示
- 重寫,則按照重寫效果顯示
-
注意
- 模板繼承時,伺服器端的動態內容無法繼承
-
演示:
http://127.0.0.1:8000/base_index
# mysite1/mysite1/urls.py
urlpatterns = [
...
path('base_index', views.base_view, name='base_index'),
path('music_index', views.music_view),
path('sport_index', views.sport_view),
]
# mysite1/mysite1/views.py
def base_view(request):
lst = ['Tom', 'Jack']
return render(request, 'base.html', locals())
def music_view(request):
return render(request, 'music.html')
def sport_view(request):
return render(request, 'sport.html')
#-------------------------------------------------------------
# mysite1/templates/base.html # 父模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% block mytitle %}
<title>主頁</title> # 子模板能改的地方
{% endblock %}
</head>
<body>
{{ lst }} # 子模板無法繼承變量(動態內容)
<a href="/music_index">音樂頻道</a> # 子模板不能改
<a href="/sport_index">體育頻道</a>
<br>
{% block info %}
這是主頁 # 子模板能改的地方
{% endblock %}
<br>
<h3>有任何問題聯繫xxxx</h3> # 子模板不能改
# mysite1/templates/music.html # 子模板
{% extends 'base.html' %} # 繼承父模板
{% block mytitle %}
<title>音樂頻道</title> # 子模板重寫block
{% endblock %}
{% block info %}
歡迎來到音樂頻道
{% endblock %}
# mysite1/templates/sport.html
{% extends 'base.html' %}
{% block mytitle %}
<title>體育頻道</title>
{% endblock %}
{% block info %}
歡迎來到體育頻道
{% endblock %}
小節#
-
過濾器
{
變數
|過濾器
1:'參數值
1' | 過濾器 2:' 參數值 2' ... } -
模板的繼承
父模板 -
定義可被修改的block
子模板 - 繼承
父模板
;按需修改父模板中定義的block
三. url 反向解析#
-
代碼中 url 出現位置
-
== 模板 == 【html 中】
-
<a ==href==='url'> 超鏈接 </a>
點擊後 頁面跳轉至 url
-
<form ==action==='url' method='post'>
form 表單中的數據 用 post 方法提交至 url
-
-
== 視圖函數 == 中 - 302 跳轉 HttpResponseRedirect ('url')
將用戶地址欄中的地址跳轉到 url
-
-
代碼中 url 書寫規範
-
== 絕對地址 ==
-
== 相對地址 ==
- '==/==page/1' - =='/' 開頭的相對地址 ==,瀏覽器會把當前地址欄裡的 協議,ip 和 端口 加上這個地址,作為最終訪問地址,即如果當前頁面地址欄為 http://127.0.0.1:8000/page/3;當前相對地址最終結果為 ==
http://127.0.0.1:8000
== + /page/1 (☆ 高頻使用) - 'page/1' - == 沒有 '/' 開頭的相對地址 ==,瀏覽器會根據
當前 url 的最後一個 / 之前的內容 加上 该相對地址
作為最終訪問地址,例如當前地址欄地址為 ==http://127.0.0.1:8000/topic/==detail;則該相對地址最終結果為 ==http://127.0.0.1:8000/topic/
== + page/1
- '==/==page/1' - =='/' 開頭的相對地址 ==,瀏覽器會把當前地址欄裡的 協議,ip 和 端口 加上這個地址,作為最終訪問地址,即如果當前頁面地址欄為 http://127.0.0.1:8000/page/3;當前相對地址最終結果為 ==
-
-
演示:
http://127.0.0.1:8000/test/url
# mysite1/mysite1/urls.py
urlpatterns = [
...
# http://127.0.0.1:8000/test/url
path('test/url', views.test_url),
path('test_url_result', views.test_url_result)
]
# mysite1/mysite1/views.py
def test_url(request):
return render(request, 'test_url.html')
def test_url_result(request):
return HttpResponse('---test url res is ok')
# mysite1/templates/test_url.html
<a href="http://127.0.0.1:8000/test_url_result">絕對地址</a>
<a href="/test_url_result">帶'/'的相對地址</a>
<a href="test_url_result">不帶'/'的相對地址</a> # 瀏覽器解析為 http://127.0.0.1:8000/test/test_url_result
-
url 反向解析
-
url 反向解析是指在視圖或者模板中,用 ==path 定義的名稱 == 來 == 動態查找或計算出相應的路由 ==
-
path 函數的語法
- path (route, views, ==name==="別名")
- path('page', views.page_view, name="page_url")
- 根據 path 中的 'name=' 關鍵字傳給 url 確定了一個唯一確定的名字,在模板或視圖中,可以通過這個名字反向推斷出此 url 信息
-
== 模板中 == - 通過 url 標籤實現地址的反向解析
{% url '別名' %} {% url '別名' '參數值1' '參數值2' %} ex: {% url 'pagen' '400' %} --- 傳參一律是 str {% url 'person' age='18' name='gxn' %}
- 演示:在模板中使用
http://127.0.0.1:8000/test/url
# mysite1/mysite1/urls.py urlpatterns = [ ... # http://127.0.0.1:8000/test/url path('test/url', views.test_url), path('test_urls_result/<int:age>', views.test_url_result, name='tr') # 起別名 tr ] # mysite1/mysite1/views.py def test_url(request): return render(request, 'test_url.html') def test_urls_result(request): return HttpResponse('---test url res is ok') # mysite1/templates/test_url.html <a href="{% url 'tr' '100' %}">url反向解析版本</a> # ☆ 模板中使用別名
-
在 == 視圖函數 == 中 → 可調用 django 中的 ==reverse== 方法進行反向解析
from django.urls import reverse reverse('別名', args=[], kwargs={}) ex: print(reverse('pagen', args=[300])) print(reverse('person', kwargs= {'name':'peng', 'age':23}))
-
演示:
http://127.0.0.1:8000/test/url # 302跳轉 - 響應頭裡的 location 標記跳轉地址
# mysite1/mysite1/urls.py urlpatterns = [ ... path('base_index', views.base_view, name='base_index'), # 起別名 base_index # http://127.0.0.1:8000/test/url path('test/url', views.test_url), path('test_urls_result/<int:age>', views.test_url_result, name='tr') # 起別名 tr ] # mysite1/mysite1/views.py def base_view(request): lst = ['Tom', 'Jack'] return render(request, 'base.html', locals()) def test_url(request): return render(request, 'test_url.html') def test_url_result(request, age): #302跳轉 from django.urls import reverse url = reverse('base_index') # ☆ 視圖函數中使用別名 return HttpResponseRedirect(url) #--------------------------------------------------------------- # mysite1/templates/test_url.html <a href="{% url 'tr' '100' %}">url反向解析版本</a> # mysite1/templates/base.html 略
-
-
四。總結#
- 請求(request)和響應(HttpResponseqing)
- GET/POST 處理 - request.GET/POST
- MVC 和 MTV
- 模板層基礎配置
- 模板變數 / 標籤 / 過濾器 / 繼承
- url 反向解析