《Django Web框架》
目錄
Django的框架模式
-
MVC 設計模式
-
MVC 代表 Model-View-Controller(模型-視圖-控制器) 模式。
-
作用: 降低模塊間的耦合度(解耦)
-
MVC
- M 模型層(Model), 主要用於對數據庫層的封裝
- V 視圖層(View), 用於向用戶展示結果
- C 控制(Controller ,用於處理請求、獲取數據、返回結果(重要)
-
如圖:
-
-
MTV 模式
MTV 代表 Model-Template-View(模型-模板-視圖) 模式。這種模式用於應用程序的分層開發- 作用:
- 降低模塊商的耦合度(解耦)
- MTV
- M – 模型層(Model) 負責與數據庫交互
- T – 模板層(Template) 負責呈現內容到瀏覽器
- V – 視圖層(View) 是核心,負責接收請求、獲取數據、返回結果
- 如圖:
- 作用:
模板 Templates
-
什麼是模板
- 模板是html頁面,可以根據視圖中傳遞的數據填充值相應的頁面元素。
- 模板層提供了一個對設計者友好的語法用於渲染向用戶呈現的信息。
-
模板的配置
- 創建模板文件夾
<項目名>/templates
- 在 settings.py 中有一個 TEMPLATES 變量
- BACKEND : 指定模板的引擎
- DIRS : 指定保存模板的目錄們
- APP_DIRS : 是否要在應用中搜索模板本
- OPTIONS : 有關模板的選項們
- 創建模板文件夾
-
默認的模塊文件夾
templates
-
修改settings.py文件,設置TEMPLATES的DIRS值爲
'DIRS': [os.path.join(BASE_DIR, 'templates')],
# file: settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [],
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 添加模板路徑
'APP_DIRS': True, # 是否索引各app裏的templates目錄
...
},
]
- 模板的加載方式
- 通過 loader 獲取模板,通過HttpResponse進行響應
from django.template import loader # 1.通過loader加載模板 t = loader.get_template("模板名稱") # 2.將t轉換成字符串 html = t.render() # 3.響應 return HttpResponse(html)
- 示例:
from django.template import loader def render_page1(request): # 1.通過loader加載模板 t = loader.get_template("page1.html") # 2.將t轉換成字符串 html = t.render() # 3.響應 return HttpResponse(html)
- 使用 render() 直接加載並響應模板
- 示例:
from django.shortcuts import render return render(request,'模板的名稱')
- 示例
def render_page2(request): from django.shortcuts import render return render(requese, 'page1.html')
- 通過 loader 獲取模板,通過HttpResponse進行響應
Django 模板語言: (The Django template language)
模板的傳參
- 模板傳參是指把數據形成字典,傳參給模板,由模板渲染來填充數據
- 使用 loader 加載模板
t = loader.get_template('xxx.html') html = t.render(字典數據) return HttpResponse(html)
- 使用render加載模板
return render(request,'xx.html',字典數據)
模板的變量
- 在模板中使用變量語法
{{ 變量名 }}
- 後端中必須將變量封裝到字典中才允許傳遞到模板上
dic = { "變量1":"值1", "變量2":"值2", }
模板的標籤
-
作用
- 將一些服務器端的功能嵌入到模板中
-
標籤語法
{% 標籤 %} ... {% 結束標籤 %}
-
if 標籤
{% if 條件表達式 %} ... {% elif 條件表達式 %} ... {% else %} ... {% endif %}
-
if 標籤裏的布爾運算符
- if 條件表達式裏可以用的運算符 ==, !=, <, >, <=, >=, in, not in, is,is not, not、and、or
- 在if標記中使用實際括號是無效的語法。 如果您需要它們指示優先級,則應使用嵌套的if標記。
-
for 標籤
- 語法
{% for 變量 in 可迭代對象 %} {% endfor %}
- 內置變量 - forloop
變量 描述 forloop.counter 循環的當前迭代(從1開始索引) forloop.counter0 循環的當前迭代(從0開始索引) forloop.revcounter 循環結束的迭代次數(從1開始索引) forloop.revcounter0 循環結束的迭代次數(從0開始索引) forloop.first 如果這是第一次通過循環,則爲真 forloop.last 如果這是最後一次循環,則爲真 forloop.parentloop 對於嵌套循環,這是圍繞當前循環的循環
- 語法
-
for … empty 標籤
- 語法
{% for 變量 in 可迭代對象 %} {% empty %} {% endfor %}
- 語法
-
cycle 標籤
- 循環從cycle 列表後的參數中進行取值,每次調用進行一次更換
- 這個標籤經常用於循環中,如處理表格的隔行變色
- 語法:
{% for o in some_list %} <tr class="{% cycle 'row1' 'row2' %}"> ... </tr> {% endfor %}
- 示例:
<table> <tr> <th>姓名</th> <th>年齡</th> <th>成績</th> </tr> <tr style="background:red;"> <td>小張</td> <td>20</td> <td>100</td> </tr> <tr style="background:blue;"> <td>小張</td> <td>20</td> <td>100</td> </tr> <tr style="background:red;"> <td>小張</td> <td>20</td> <td>100</td> </tr> <tr style="background:blue;"> <td>小張</td> <td>20</td> <td>100</td> </tr> <!-- 以下可以用cycle 標籤完成 --> {% for s in students %} <tr style="background: {% cycle 'red' 'yellow' %};"> <td>{{ s.name }}</td> <td>{{ s.age }}</td> <td>{{ s.score }}</td> </tr> {% endfor %} </table>
-
註釋 和 comment標籤
- 以
{#
開頭, 以#}
結束範圍內的文字信息將會被模板的渲染系統忽略掉 - 如:
{# <h1>此處的文字不會被生成html文檔</h1> #}
- comment 標籤
- 在 {% comment %} 和 {% endcomment %},之間的內容會被忽略,
- 作用: 用於註釋,可以用此來記錄代碼被註釋掉的原因。
- 注: comment 標籤不能嵌套使用
- 例如:
<div>Rendered text with {{ pub_date|date:"c" }}</div> {% comment "Optional note" %} <div>Commented out text with {{ create_date|date:"c" }}</div> {% endcomment %} comment標籤不能嵌套使用。
過濾器
-
作用
- 在變量輸出前對變量的值進行處理
- 您可以通過使用 過濾器來改變變量的顯示。
-
語法
- {{變量|過濾器1:參數值1|過濾器2:參數值2 …}}
-
有用的過濾器
過濾器 說明 default 如果value的計算結果爲False,則使用給定的默認值。 否則,使用該value。 default_if_none 如果(且僅當)value爲None,則使用給定的默認值。 否則,使用該value。 floatformat 當不使用參數時,將浮點數舍入到小數點後一位,但前提是要顯示小數部分。 truncatechars 如果字符串字符多於指定的字符數量,那麼會被截斷。 截斷的字符串將以可翻譯的省略號序列(“…”)結尾。 truncatewords 在一定數量的字後截斷字符串。 lower 將字符串轉換爲全部小寫。 upper 將字符串轉換爲大寫形式 … -
escape 示例:
- escape 轉義字符串的HTML。 具體來說,它使這些替換:
< 轉換爲 < > 轉換爲 > '(單引號)轉換爲 ' "(雙引號)轉換爲 " & 轉換爲 &
-
文檔參見:
模板的繼承
-
模板繼承可以使父模板的內容重用,子模板直接繼承父模板的全部內容並可以覆蓋父模板中相應的塊
-
定義父模板中的塊
block
標籤- 標識出哪些在子模塊中是允許被修改的
- block標籤:在父模板中定義,可以在子模板中覆蓋
{% block block_name %} 定義模板塊,此模板塊可以被子模板重新定義的同名塊覆蓋 {% endblock block_name %}
-
繼承模板
extends
標籤(寫在模板文件的第一行)- 子模板繼承語法標籤
{% extends '父模板名稱' %}
- 如:
{% extends 'base.html' %}
- 子模板 重寫父模板中的內容塊
{% block block_name %} 子模板塊用來覆蓋父模板中 block_name 塊的內容 {% endblock block_name %}
- 重寫的覆蓋規則
- 不重寫,將按照父模板的效果顯示
- 重寫,則按照重寫效果顯示
- 注意
- 模板繼承時,服務器端的動態內容無法繼承
- 子模板繼承語法標籤
-
參考文檔
-
模板的繼承示例:
# file : url.py from django.conf.urls import url from . import views urlpatterns = [ ... url(r'^index', views.index), url(r'^goods_list1', views.goods_list), url(r'^goods_list2', views.goods_list2), url(r'^user_info1', views.user_info1), url(r'^user_info2', views.user_info2), ] # file: views.py def index(request): return render(request, 'index.html') def goods_list(request): return render(request, 'goods_list.html') def goods_list2(request): return render(request, 'goods_list2.html') def user_info1(request): return render(request, 'user_info_page1.html') def user_info2(request): return render(request, 'user_info_page2.html')
- 基類模板
<!-- file : base.html --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>{% block title %}{% endblock %}</title> <style> /* 基礎樣式設置 */ body, h1, h2, h3, h4, h5, h6, p, ul, ol { margin: 0; padding: 0; border: 0; list-style: none; } /* 整體 */ #container { width: 1000px; margin: 0 auto; } /* 頂部 */ #top { width: 1000px; height: 100px; background: gray; } /* 主體 */ #main { display: flex; justify-content: space-between; } {% block head_style %} {% endblock %} /* 底部 */ #foot { width: 1000px; height: 100px; background: orange; } </style> </head> <body> <!-- 整體 --> <div id="container"> <!-- 1.頂部 --> <div id="top"> 標題 </div> <!-- 2.中間主體部分 --> <div id="main"> {% block body_info %} {% endblock %} </div> <!-- 3.底部 --> <div id="foot"> 底部 </div> </div> </body> </html>
- 子類主頁模板
{% extends "base.html" %} {% block title %}首頁{% endblock %} {% block head_style %} /* 主體左側 */ #main #main_index { width: 1000px; height: 500px; background: pink; } {% endblock %} {% block body_info %} <!-- 2.1 主面中間的信息 --> <div id="main_index"> 主頁 </div> {% endblock %}
- 子類商品列表模板
{% extends "base.html" %} {% block title %}商品列表{% endblock %} {% block head_style %} /* 主體左側 */ #main #left-type{ width:300px; height:500px; background:pink; } /* 主體右側 */ #main #right-goods{ width:700px; height:500px; background:blue; } {% endblock %} {% block body_info %} <!-- 2.1 主面中間的信息 --> <!-- 2.1主體左邊 --> <div id="left-type"> <ul> <li>手機</li> <li>電腦</li> <li>戶車</li> </ul> </div> {% block goods_info %} <div id="right-goods"> 手機列表 </div> {% endblock %} {% endblock %}
{% extends "goods_list.html" %} {% block goods_info %} <div id="right-goods"> 電腦列表 </div> {% endblock %}
{# 此模板繼承自base.html #} {% extends "base.html" %} {% block title %}用戶信息{% endblock %} {% block head_style %} /* 主體左側 */ #main #left-list{ width:300px; height:500px; background:pink; } /* 主體右側 */ #main #right-info{ width:700px; height:500px; background:yellow; } {% endblock %} {% block body_info %} <!-- 2.1 主面中間的信息 --> <!-- 2.1主體左邊 --> <div id="left-list"> <ul> <li>修改密碼</li> <li>修改頭像</li> <li>修改聯繫方式</li> </ul> </div> {% block user_detail %} <div id="right-info"> <div>原密碼<input type="password"></div> <div>新密碼<input type="password"></div> <div>新密碼<input type="password"></div> </div> {% endblock %} {% endblock %}
{# 此模板繼承自user_info_page1.html #} {% extends "user_info_page1.html" %} {% block user_detail %} <div id="right-info"> <div>手機號<input type="text"></div> <div>家庭住址<input type="text"></div> </div> {% endblock %}
url 反向解析
- url()的
name
關鍵字參數- 作用:
- 根據url 列表中的
name=
關鍵字傳參給 url確定了個唯一確定的名字,在模板中,可以通過這個名字反向推斷出此url信息
- 根據url 列表中的
- 語法
- url(regex, views, kwargs=None, name=“別名”)
- ex:
- url(r’^user_login/$’, views.login, name=“login”)
- 通過別名實現地址的反向解析
在模板中: {% url ‘some-url-name’ %}
{% url ‘別名’ %}
{% url ‘別名’ ‘參數值1’ ‘參數值2’ %} - 示例:
# file: url.py from django.conf.urls import url from . import views urlpatterns = [ ... url(r'^fav_list', views.fav_list, name="fav_list"), url(r'^fav_list/page/(\d+)', views.fav_list_page, name="fav_list_page"), ] # file: views.py def fav_list(request): return render(request, 'fav_list.html') def fav_list_page(request, page): return render(request, 'fav_list.html')
<html> <head></head> <body> <div><a href="/fav_list">我的收藏</a></div> <div><a href="{% url "fav_list" %}">我的收藏</a></div> <a href="/fav_list/page/1">我的收藏第1頁</a> <a href="/fav_list/page/2">我的收藏第2頁</a> <a href="/fav_list/page/3">我的收藏第3頁</a> <a href="{% url 'fav_list_page' '200' %}">我的收藏第4頁</a> </body> </html>
- 作用:
靜態文件
- 什麼是靜態文件
- 不能與服務器端做動態交互的文件都是靜態文件
- 如:圖片,css,js,音頻,視頻,html文件(部分)
- 靜態文件配置
- 在 settings.py 中配置一下兩項內容:
- 配置靜態文件的訪問路徑
- 通過哪個url地址找靜態文件
- STATIC_URL = ‘/static/’
- 說明:
- 指定訪問靜態文件時是需要通過 /static/xxx或 127.0.0.1:8000/static/xxx
- xxx 表示具體的靜態資源位置
- 配置靜態文件的存儲路徑
- 靜態文件在服務器端的保存位置
- STATICFILES_DIRS=(os.path.join(BASE_DIR,‘static’),)
- 示例:
# file: setting.py STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static") ]
- 訪問靜態文件
-
使用靜態文件的訪問路徑進行訪問
- 訪問路徑: STATIC_URL=/static/
- 示例:
<img src="/static/images/lena.jpg"> <img src="http://127.0.0.1:8000/static/images/lena.jpg">
-
通過 {% static %}標籤訪問靜態文件
{% static %}表示的就是靜態文件訪問路徑- 加載 static
{% load static %} - 使用靜態資源時
語法:{% static ‘靜態資源路徑’ %}
<img src="{% static ‘images/lena.jpg’ %}">
- 加載 static
- 示例:
# file: url.py from . import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^show_image', views.show_image) ] # file: views.py from django.shortcuts import render def show_image(request): return render(request, "show_image.html")
<html> <head></head> <body> <h1>this is lena!</h1> <img src="/static/images/lena.jpg"> <h1>this is templates lena!</h1> {% load static %} <img src="{% static 'images/lena.jpg' %}"> </body> </html>
-
Django中的應用 - app
什麼是應用(app)
- 應用在Django項目中是一個獨立的業務模塊,可以包含自己的路由,視圖,… …
- Django中,主文件夾是不處理用戶具體請求的.主文件夾的作用是做項目的初始化以及請求的分發(分佈式請求處理).具體的請求是由應用來進行處理的
創建應用app
- 創建應用的指令
- python3 manage.py startapp 應用名稱
- 如:
- python3 manage.py startapp music
Django應用的結構組成
1. `migrations` 文件夾
- 保存數據遷移的中間文件
2. `__init__.py`
- 應用子包的初始化文件
3. `admin.py`
- 應用的後臺管理配置文件
4. `apps.py`
- 應用的屬性配置文件
5. `models.py`
- 與數據庫相關的模型映射類文件
6. `tests.py`
- 應用的單元測試文件
7. `views.py`
- 定義視圖處理函數的文件
- 配置安裝應用
- 在 settings.py 中配置應用, 讓此應用能和整個項目融爲一體
# file : settings.py INSTALLED_APPS = [ ... ..., '自定義應用名稱' ]
- 如:
INSTALLED_APPS = [ # .... 'user', # 用戶信息模塊 'music', # 收藏模塊 ]
- 在 settings.py 中配置應用, 讓此應用能和整個項目融爲一體
- 應用的分佈式路由
- 使用include 函數讓某個正則匹配後關聯分支到某個app
# file : <項目名>/urls.py from django.conf.urls import include urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^music/', include('music.urls')), url(r'^sport/',include('sport.urls')), url(r'^news/',include('news.urls')), ] # file : <App名>/urls.py from django.conf.urls import url from . import views urlpatterns = [ # 購物車模塊用到的路由 url(r'^page1', views.page1), url(r'^page2', views.page2), url(r'^page3', views.page3), # ... ]
end…