本篇文章是 Django 類別基礎視圖 (CBV) 系列的第五篇,將介紹如何利用 CreateView、UpdateView、DeleteView 輕鬆實現 CRUD 功能。結合前面提到的 ListViewDetailView,不僅可以進行 數據查詢,還可以快速構建完整的 CRUD 應用程序,包括 創建(Create)修改(Update)刪除(Delete) 的功能。

尚未閱讀前一篇文章 ListView、DetailView 的讀者,建議您先閱讀那篇文章。

類別基礎視圖(CBV)探討系列 ④ - ListView & DetailView 的使用方法


“使用 Django 的通用視圖輕鬆完成 CRUD,並最大化生產力!”

在之前的文章中,我們專注於 CBV 的基本結構以及通過 ListViewDetailView 進行的 讀取(READ) 操作。
這篇文章將探討 Django 提供的便捷 CreateViewUpdateViewDeleteView,通過這些視圖,我們將系統性地完成具有 創建(Create)修改(Update)刪除(Delete) 功能的網頁應用程序。


1. CreateView – 創建數據

1.1 基本概念與結構

CreateView 是 Django 通用視圖中專門用於“創建新對象”的類。

  • 自動化表單處理: 通過內部利用 FormView 的功能,在 form_valid() 中保存新對象並在成功時重新定向到指定 URL。

  • ModelForm 協作良好: 指定 model 屬性和 fields,或 form_class,表單將自動生成並處理。

# views.py
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Post

class PostCreateView(CreateView):
    model = Post
    fields = ['title', 'content']  # 或者 form_class = PostForm
    template_name = 'post_form.html'
    success_url = reverse_lazy('post_list')  # 創建成功後將重定向到的 URL

1.2 urls.py 連接範例

# urls.py
from django.urls import path
from .views import PostCreateView

urlpatterns = [
    path('posts/create/', PostCreateView.as_view(), name='post_create'),
]

1.3 模板範例: post_form.html

<!DOCTYPE html>
<html>
<head>
    <title>撰寫新文章</title>
</head>
<body>
    <h1>撰寫新帖子</h1>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">保存</button>
    </form>
</body>
</html>

提示: 使用 form_class 而不是 fields,您可以在 forms.py 中定義 ModelForm 來更精細地控制表單。


2. UpdateView – 修改數據

2.1 基本概念與結構

UpdateView 是一種專門用於查找並修改 現有對象 的通用視圖。

  • 使用 URL 中的 pkslug 值自動查找相應對象。

  • 在表單中自動填充現有數據並進行渲染,當用戶修改後提交時,將更改保存到數據庫。

# views.py
from django.views.generic.edit import UpdateView
from django.urls import reverse_lazy
from .models import Post

class PostUpdateView(UpdateView):
    model = Post
    fields = ['title', 'content']
    template_name = 'post_form.html'
    success_url = reverse_lazy('post_list')  # 修改成功後將重定向到的 URL

2.2 urls.py 連接範例

# urls.py
from .views import PostUpdateView

urlpatterns = [
    path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),
]

2.3 模板範例 (可重用)

CreateView 一樣,可以重用 post_form.html 模板。
UpdateView 中,form.instance 已經是存儲在數據庫中的對象,因此現有數據會自動填入表單。


3. DeleteView – 刪除數據

3.1 基本概念與結構

DeleteView 是一種用於查找並 刪除 特定對象的通用視圖。

  • 當用戶提交刪除確認表單時,該對象將從數據庫中移除,並將重新定向至指定的 URL。

  • 出於安全考量,建議您建立一個“刪除確認”模板。

# views.py
from django.views.generic.edit import DeleteView
from django.urls import reverse_lazy
from .models import Post

class PostDeleteView(DeleteView):
    model = Post
    template_name = 'post_confirm_delete.html'
    success_url = reverse_lazy('post_list')

3.2 urls.py 連接範例

# urls.py
from .views import PostDeleteView

urlpatterns = [
    path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]

3.3 模板範例: post_confirm_delete.html

<!DOCTYPE html>
<html>
<head>
    <title>刪除文章</title>
</head>
<body>
    <h1>刪除文章</h1>
    <p>您確定要刪除這篇文章嗎?</p>
    <form method="post">
        {% csrf_token %}
        <button type="submit">刪除</button>
        <a href="{% url 'post_list' %}">取消</a>
    </form>
</body>
</html>

注意: DeleteView 設計上需經過“刪除確認”過程,以防止使用者的誤刪除。
如果希望立即刪除,則需通過其他方式實現(例如: FormView 或直接編寫邏輯)。


4. 一覽 CRUD 完成流程

CRUD 概念圖 – 4 種操作, 5 種視圖

4.1 示例模型: Post

# models.py
class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.title

4.2 urlpatterns (簡略版本)

urlpatterns = [
    # 1) 讀取
    path('posts/', PostListView.as_view(), name='post_list'),                   # 列表(ListView)
    path('posts/<int:pk>/', PostDetailView.as_view(), name='post_detail'),      # 詳細(DetailView)

    # 2) 創建
    path('posts/create/', PostCreateView.as_view(), name='post_create'),

    # 3) 修改
    path('posts/<int:pk>/edit/', PostUpdateView.as_view(), name='post_update'),

    # 4) 刪除
    path('posts/<int:pk>/delete/', PostDeleteView.as_view(), name='post_delete'),
]

4.3 建議的資料夾結構和模板文件

  • templates/

    • post_list.html

    • post_detail.html

    • post_form.html (CreateView, UpdateView 共用)

    • post_confirm_delete.html (DeleteView)


5. 如何自定義 Create/Update/DeleteView

5.1 使用 form_class 來細分表單控制

class PostCreateView(CreateView):
    model = Post
    form_class = PostForm  # 指定 ModelForm
    ...

PostForm 中,可以細緻設置 字段驗證小部件設置,以實現更靈活的表單處理。

5.2 使用 get_success_url() 動態重定向

def get_success_url(self):
    # 例如: 使用新創建的 Post 的 pk 移動到詳細頁面
    return reverse_lazy('post_detail', kwargs={'pk': self.object.pk})

self.object 是指當前在 Create/Update 中處理的模型實例。

5.3 控制訪問權限,增加 Mixin

  • 可以與 LoginRequiredMixin 等組合,製作“只有登錄用戶可以創建/修改/刪除”的規則。

  • 如果希望更細致地管理權限,可以考慮 PermissionRequiredMixinUserPassesTestMixin


6. 與 FBV 進行比較

功能 FBV (函數基礎視圖) Create/Update/DeleteView (類別基礎視圖)
創建(Create) request.method == 'POST' 條件語句,直接定義 ModelForm,保存邏輯直接編寫 CreateView: 繼承後自動處理表單生成→保存→重定向
修改(Update) 拉取現有對象再放入表單,POST 處理時再進行验证与保存邏輯的重復 UpdateView: 拉取現有對象→修改→保存,邏輯自動化
刪除(Delete) GET→渲染刪除確認頁,POST→處理刪除,重定向等所有邏輯混合在函數內 DeleteView: 獲取待刪除對象,自動提供刪除後的移動處理邏輯
可讀性 / 維護性 邏輯分支多,代碼容易變長,在多處重複相同邏輯 方法覆寫僅重寫必要部分,最小化重複
開發生產力(核心關鍵字) “手工操作較多,耗時,代碼重複” “提高開發速度(節省時間)和維護性提升(生產力增強)”

FBV 與 CBV – 裝配家具比喻


7. 總結: 通過通用視圖快速而乾淨地實現 CRUD!

使用 CreateViewUpdateViewDeleteView,您可以在 Django 中以極其簡潔和直觀的代碼完成 CRUD 操作。
特別是 重複的表單處理邏輯數據保存後重定向 的模式會自動處理,因此開發者需要專注的部分是“業務邏輯”和“UI/UX”。

如果您已經理解了 ListView + DetailView + CreateView + UpdateView + DeleteView,那麼您將能輕鬆構建一個基本的 CRUD 應用程序!

在下一篇文章中,我們將介紹 TemplateView & RedirectView,並探討如何順利自動化 簡單頁面渲染重定向 的處理。


再次查看前一篇文章

  1. 類別基礎視圖(CBV)探討系列 #1 – 從 FBV 轉向 CBV 的原因及開發者的心態

  2. 類別基礎視圖(CBV)探討系列 #2 – 理解 Django 的基本 View 類

  3. 類別基礎視圖(CBV)探討系列 #3 – 使用 FormView 簡化表單處理

  4. 類別基礎視圖(CBV)探討系列 #4 – ListView & DetailView 的使用方法


“利用 Django 的通用視圖自動化 CRUD 實現,
同時提升項目開發速度與代碼質量!”