iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 25
2
Modern Web

From Django 1.11 to Django 2.1 系列 第 25

Day25 : Django Class-Based Views (CBV)

經過了這麼長的一段時間,相信你對 Django 基礎的運作模式一定相當熟悉了,大致上就這四步

  1. Model
  2. View
  3. Template
  4. Url

有了 Model,等於是擁有了資料庫雛形,接著在 View 處理 商業邏輯,取得我們想要顯示的資料,然後在 Template決定我們資料要怎麼擺飾! 最後再將 網址view 作對應

使用 Django 來建一個網頁是相當輕鬆的一件事情 ^^

而當你這麼想的時候,Django就跳出來了並說了一句
https://ithelp.ithome.com.tw/upload/images/20181025/20111829bGM21glPNu.jpg

因為在這之前我們在 views 所撰寫的商業邏輯都單純只是一個function,雖然使用它就可以幫我們處理相當多的事情,但是他並不具備著 類別繼承 的特性

貼心的 Django 為了方便我們開發,都幫我們鋪好路了,提供了許多內建的 Class-Based Views,而我們只要去繼承它們,便能幫助我們完成相當多的事情,廢話不多說,直接帶大家來看範例吧!


我們來創建兩個 Class-Based Views,分別是

  1. ListView
  2. DetailView
# views.py
from django.views.generic import ListView, DetailView # 新增

# Create your views here.
# 繼承 ListView
class VendorListView(ListView):
    model = Vendor
    template_name = 'vendor/vendor_list.html'

# 繼承 DetailView
class VendorDetail(DetailView):
    model = Vendor
    # queryset = Vendor.objects.all()
    template_name = 'vendor/vendor_detail.html'
  • model : 我們要使用哪一個 Model,更白話就是我們要使用哪一個資料庫,它與 queryset = Vendor.objects.all()是同義的,而queryset的好處就是我們能夠拿我們想要的資料( 還記得嗎? 透過 filter 我們可以只取得部分資料),而前者 model = Vendor 是一個 簡易 (Shorthand) 的寫法
  • template_name : 我們要使用哪一個 template,命名之後才能覆寫唷!

寫好了 template的位址,接下來要在指定的目錄寫 vendor_lst.html 及 vendor_detail.html

# vendor_lst.html 
{% extends 'base.html' %}
{% block content %}
{% for vendor in object_list %}
 <div class="">
   <h2><a href="{% url 'vendors:vendor_id' vendor.id %}">{{ vendor.store_name }}</a></h2>
   <p>{{ vendor.vendor_name }}</p>
 </div>
{% endfor %}
{% endblock content %}


# vendor_detail.html
{% extends "base.html" %}
{% block title %} My store {% endblock %}
{% block content%}
<h1> 店家 : {{ vendor.vendor_name}} </h1>
<ul>
  <li>店名 : {{ vendor.store_name}}</li>
  <li>電話 : {{ vendor.phone_number}}</li>
  <li>地址 : {{ vendor.address}}</li>
</ul>
{% endblock %}

這裡你要注意的地方有 :

  • object_list: 當我們使用 Listview,它會回傳 object_list,所有的 Vendor 資料都會存在裡面,又因為它是 queryset 的型態,所以我們必須使用 for-loop 來存取它
  • vendor_detail.html : 存取DetailView的方式比較特別,你可以使用 object or 小寫的 Model name - vendor

接著修改一下 urls.py

urlpatterns = [
    path('', VendorListView.as_view(), name='index'),
    path('<int:id>/', VendorDetailView.as_view(), name='vendor_id'),
  • as_view() : 當你使用了內建的類別,就是要透過as_view()的方式,讓它變得跟原本呼叫函式一樣,也就是 views.<somefunctions> 之類的

如此一來你便能透過 ListView 及 DetailView 更簡易的來完成之前我們所做的事情囉 ^^"
https://ithelp.ithome.com.tw/upload/images/20181025/20111829VQSSKsnuuf.jpg
https://ithelp.ithome.com.tw/upload/images/20181025/20111829LlygZnlPzw.jpg


今日小節

今天主要跟大家介紹更多 Django 幫我們造好的輪子,雖然說它真的很方便,不過相對的,因為它是由一大堆的類別繼承下來的一個模板,所以實際上你要記得名稱就比較多,好用的方法,但勢必有它的規則要遵循 ^^"


上一篇
Day24 : 深入探討 命名空間
下一篇
Day26 : Django - CBV (續)
系列文
From Django 1.11 to Django 2.1 30

1 則留言

0
lighthola
iT邦新手 5 級 ‧ 2019-04-26 11:59:43

Hi,

我在實作的時候發現在使用DetailView時,path需要將 '<int:id>/' 修改成 '<int:pk>/' 才不會有錯誤出現。

我要留言

立即登入留言