django

django就是有MTV
原來(lái)的控制的C由框架自己搞定了,
M就是Model,寫(xiě)的是業(yè)務(wù)對(duì)象和數(shù)據(jù)庫(kù)的關(guān)系,從數(shù)據(jù)庫(kù)讀取數(shù)據(jù),給視圖View獲取和返回?cái)?shù)據(jù)
T是模板,給用戶展示內(nèi)容

V和T是展示哪些數(shù)據(jù)和模板怎么展現(xiàn)兩部分

以要增加書(shū)籍為例
首先在T上,要有一個(gè)html寫(xiě)這個(gè)


image.png

這個(gè)里面有一個(gè)url 'lib:addBook2'對(duì)應(yīng)的是addBook2,要在url.py里和View連起來(lái) ,url.py里有path('addBook5/',views.addBook,name='addBook2'),

MVC

在說(shuō) MTV 模式之前,讓我們來(lái)簡(jiǎn)單的說(shuō)說(shuō)著名的 MVC 模式。

MVC,是模型(Model)-視圖(View)-控制器(Controller)的縮寫(xiě)。其具體定義如下:

  • M:模型(Model),數(shù)據(jù)存取層,負(fù)責(zé)業(yè)務(wù)對(duì)象和數(shù)據(jù)庫(kù)對(duì)象。
  • V:視圖(View),與用戶的交互,負(fù)責(zé)顯示與怎樣顯示。
  • C:控制器(Controller),接受用戶動(dòng)作,調(diào)用模型,輸出相應(yīng)視圖。

三者以一種插件似的,松耦合的方式連接在一起。

7-2.1-1

MTV

Django 的 MTV 設(shè)計(jì)模式是借鑒和遵循 MVC 的。

MTV 具體定義如下:

  • M:模型(Model),負(fù)責(zé)業(yè)務(wù)對(duì)象和數(shù)據(jù)庫(kù)的關(guān)系映射。
  • T:模板(Template),負(fù)責(zé)如何把頁(yè)面展示給用戶。
  • V:視圖(View),負(fù)責(zé)業(yè)務(wù)邏輯,并在適當(dāng)時(shí)候調(diào)用模型和模板。

URL 分發(fā)器

URL 分發(fā)器的作用是將頁(yè)面請(qǐng)求分發(fā)給不同的視圖(View)處理,視圖再調(diào)用相應(yīng)的模型(Model)和模板(Template)。

Django Web 框架:

7-2.1-2

一個(gè)誤區(qū)是把 MVC 模式與 MTV 模式等價(jià)替換。其實(shí)這樣是不對(duì)的。

在 MTV 模式中,MVC 中的 View 分成了視圖 View(展現(xiàn)哪些數(shù)據(jù))和模板 Template(如何展現(xiàn))2 個(gè)部分,而控制器(Controller)這個(gè)要素由框架自己來(lái)實(shí)現(xiàn)了,我們需要做的就是把 URL 對(duì)應(yīng)到視圖 V 就可以了,通過(guò)這樣的 URL 配置,系統(tǒng)將一個(gè)請(qǐng)求發(fā)送到一個(gè)合適的視圖。

設(shè)計(jì)表單

在上一個(gè)實(shí)驗(yàn)中的 myApp/templates/myApp/detail.html 里,添加一個(gè)表單。

<form action="" method="post" name="addBook">
  {% csrf_token %}
  <p><span>書(shū)名:</span><input type="text" name="name" /></p>
  <p><span>作者:</span><input type="text" name="author" /></p>
  <p><span>出版社:</span><input type="text" name="pub_house" /></p>
  <input type="submit" value="添加" />
</form>

簡(jiǎn)要說(shuō)明:

  • 上面的模板是輸入相應(yīng)的書(shū)名、作者和出版社后,點(diǎn)擊添加,將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)并刷新頁(yè)面顯示出來(lái)。
  • 我們?cè)O(shè)置表單的 action="/addBook/",并設(shè)置 method="post"。使用 method="post"(與其相對(duì)的是 method="get")是非常重要的,因?yàn)檫@個(gè)提交表單的行為會(huì)改變服務(wù)器端的數(shù)據(jù),無(wú)論何時(shí),當(dāng)你需要?jiǎng)?chuàng)建一個(gè)改變服務(wù)器端數(shù)據(jù)的表單時(shí),請(qǐng)使用 method="post"。這不是 Django 的特定技巧,這是優(yōu)秀的網(wǎng)站開(kāi)發(fā)技巧。
  • 由于我們創(chuàng)建一個(gè) POST 表單(它具有修改數(shù)據(jù)的作用),所以我們需要小心跨站點(diǎn)請(qǐng)求偽造。 但你不必太過(guò)擔(dān)心,因?yàn)?Django 已經(jīng)擁有一個(gè)用來(lái)防御它的非常容易使用的系統(tǒng)。 簡(jiǎn)而言之,所有針對(duì)內(nèi)部 URL 的 POST 表單都應(yīng)該使用 {% csrf_token %} 模板標(biāo)簽。

命名空間:

教程項(xiàng)目只有一個(gè)應(yīng)用 myApp。在一個(gè)真實(shí)的 Django 項(xiàng)目中,可能會(huì)有五個(gè),十個(gè),二十個(gè),甚至更多應(yīng)用。Django 如何分辨重名的 URL 呢?

舉個(gè)例子,myApp 應(yīng)用有 detail 視圖,可能另一個(gè)博客應(yīng)用也有同名的視圖。Django 如何知道 action="" 標(biāo)簽到底對(duì)應(yīng)哪一個(gè)應(yīng)用的 URL 呢?

答案是:在根 URLconf 中添加命名空間。在 myProject/urls.py 文件中稍作修改,加上 app_name 設(shè)置命名空間:

from django.contrib import admin
from django.urls import path
from myApp import views

app_name = 'myApp' # 添加這一行
urlpatterns = [
    # path('admin/', admin.site.urls),
    path('', views.detail, name='detail'),
    path('addBook/', views.addBook, name='addBook'),
]

現(xiàn)在回到 myApp/templates/myApp/detail.html 更改 action

<form action="/addBook/" method="post" name="addBook"></form>

添加書(shū)籍

創(chuàng)建 addBook 函數(shù)來(lái)實(shí)現(xiàn)我們添加書(shū)籍的功能。

將下面的代碼添加到 myApp/views.py:

# myApp/views.py
from django.http import HttpResponseRedirect
from django.urls import reverse

def addBook(request):
    if request.method == 'POST':
        temp_name = request.POST['name']
        temp_author = request.POST['author']
        temp_pub_house = request.POST['pub_house']

    from django.utils import timezone
    temp_book = Book(name=temp_name, author=temp_author, pub_house=temp_pub_house, pub_date=timezone.now())
    temp_book.save()

    # 重定向
    return HttpResponseRedirect(reverse('detail'))

在 myProject/urls.py 里添加 URL 地址映射:

# myProject/urls.py
path('addBook/', views.addBook, name='addBook'),

簡(jiǎn)單說(shuō)明:

  • request.POST 是一個(gè)類字典對(duì)象,可以通過(guò)關(guān)鍵字的名字獲取提交的數(shù)據(jù)。 這個(gè)例子中,request.POST['name'] 以字符串形式返回name的值。request.POST 的值永遠(yuǎn)是字符串。
  • 在添加書(shū)籍之后,代碼返回一個(gè) HttpResponseRedirect 而不是常用的 HttpResponse,HttpResponseRedirect 只接收一個(gè)參數(shù):用戶將要被重定向的 URL。
  • 你應(yīng)該在每次處理 POST 數(shù)據(jù)時(shí),都返回HttpResponseRedirect。這也不是 Django 的特定技巧,這是優(yōu)秀的網(wǎng)站開(kāi)發(fā)的實(shí)踐。
  • 在這個(gè)例子中,我們?cè)?HttpResponseRedirect 的構(gòu)造函數(shù)中使用 reverse() 函數(shù)。這個(gè)函數(shù)避免了我們?cè)谝晥D函數(shù)中硬編碼 URL。它需要我們給出想要跳轉(zhuǎn)的視圖的名字和該視圖所對(duì)應(yīng)的 URL 模式中需要給該視圖提供的參數(shù)。reverse() 調(diào)用后將返回這樣一個(gè)字符串:/detail/。

添加書(shū)籍功能完成,現(xiàn)在可以隨意添加書(shū)籍。

打開(kāi) Web 服務(wù)訪問(wèn)鏈接就可以查看效果:

添加前:

6-2.2-1

添加后:

6-2.2-2

刪除書(shū)籍
刪除書(shū)籍功能實(shí)現(xiàn)起來(lái)也很簡(jiǎn)單。

首先,在 myApp/detail.html 中設(shè)計(jì)我們的模板。

{% for book in book_list.all %}
    <tr>
        <td>{{ book.name }}</td>
        <td>{{ book.author }}</td>
        <td>{{ book.pub_house }}</td>
        <td>{{ book.pub_date }}</td>
        <td><a href="{% url 'delBook' book.id %}">刪除</a></td><!--只添加這一行-->
    </tr>
{% endfor %}
</table>

可以看出,只需要在每個(gè)書(shū)籍后面添加一個(gè)刪除的按鈕。刪除時(shí)也傳遞了需要?jiǎng)h除的圖書(shū)的 id。

接著,配置 url,只需在 myProject/urls.py 中添加這一行:

# myProject/urls.py
path('delBook/<int:book_id>', views.deleteBook, name='delBook'),

這里 <int:book_id> 是接收傳遞的參數(shù) book_id。

最后設(shè)計(jì)視圖函數(shù):

# myApp/views.py
def deleteBook(request, book_id):
    bookID = book_id
    Book.objects.filter(id=bookID).delete()

    # 重定向
    return HttpResponseRedirect(reverse('detail'))

這個(gè)視圖中,獲取到 book 的 id,根據(jù) id 來(lái)刪除指定書(shū)籍。最后跟上面的添加書(shū)籍函數(shù)相同,使用重定位刷新頁(yè)面。

打開(kāi) Web 服務(wù)訪問(wèn)鏈接查看效果:

刪除后:

6-2.3-1

學(xué)習(xí)資料來(lái)自實(shí)驗(yàn)樓

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容