在 Django 中實現留言刪除功能:完整指南

更新日期: 2024 年 11 月 26 日

本指南將引導您如何在 Django 中實現刪除留言的功能,包括模板設計、URL 配置、視圖函數,以及不同應用間的交互流程。


調整模板以支持刪除留言

我們需要修改 resumes 應用中的 show.html,為每條留言新增一個刪除按鈕。

調整後的模板

{% extends "shared/layout.html" %}

{% block content %}

{% if messages %}
    <div class="alert-box">
        {% for message in messages %}
            <div class="alert {{ message.tags }}">{{ message }}</div>
        {% endfor %}
    </div>
{% endif %}

<h1>show! {{ resume.title }}</h1>
<h3>{{ resume.skill }}</h3>

<article>
    <p>{{ resume.location }}</p>
    <p>{{ resume.content }}</p>
</article>
<footer>
    <a href="{% url 'resumes:edit' resume.id %}">編輯</a>
    <a href="{% url 'resumes:delete' resume.id %}">刪除</a>
</footer>

<section>
    <form action="{% url 'resumes:comments' resume.id %}" method="post">
        {% csrf_token %}
        <textarea name="content"></textarea>
        <button type="submit">新增留言</button>
    </form>
</section>

<ul>
    {% for comment in comments %}
    <li>
        {{ comment.content|linebreaksbr }}
        <form action="{% url 'comments:delete' comment.id %}" method="post">
            {% csrf_token %}
            <button type="submit"></button>
        </form>
        <small>{{ comment.created_at }}</small>
    </li>
    {% endfor %}
</ul>

{% endblock %}

模板中的設計與表單重點

在 Django 中,刪除操作需要依賴 HTML 表單進行提交,以下是設計重點:

為什麼需要表單提交來刪除留言

  1. HTML 表單的限制
    HTML 原生僅支持 GETPOST 方法,並不提供原生的 DELETE 方法。因此,我們採用 POST 方法來模擬刪除操作。
  2. 使用 csrf_token 提升安全性
    Django 使用 CSRF(跨站請求偽造)保護機制,要求表單中包含唯一的 csrf_token,確保提交的請求來自合法來源。

刪除留言的表單代碼

以下是模板中的刪除留言代碼:

<form action="{% url 'comments:delete' comment.id %}" method="post">
    {% csrf_token %}
    <button type="submit"></button>
</form>
  • action="{% url 'comments:delete' comment.id %}"
    生成指向刪除操作的動態路徑,例如 /comments/2
  • method="post"
    使用 POST 方法提交表單,符合 Django 的安全要求。
  • {% csrf_token %}
    保護表單提交,避免未經授權的請求。

路徑設計的簡化

  1. 簡單的路徑設計
    刪除操作的路徑設計為 /comments/<comment_id>,例如 /comments/2,避免過於冗長的多級路徑(如 /resumes/<resume_id>/comments/<comment_id>)。
  2. 路徑簡化的好處
    • 符合 RESTful API 的設計原則,專注於對 Comment 資源進行操作。
    • 減少冗餘資訊,提高維護性。

配置 URL 路由

comments 應用中新增 urls.py,配置刪除留言的路由。

comments/urls.py

from django.urls import path
from . import views

app_name = "comments"

urlpatterns = [
    path("<int:id>", views.delete, name="delete"),
]
  • <int:id>:捕獲需要刪除的留言的 ID。
  • name="delete":為此路由定義名稱,便於模板中使用 {% url 'comments:delete' comment.id %}

實現刪除功能的視圖

comments 應用的 views.py 中新增刪除留言的函數。

comments/views.py

from django.shortcuts import get_object_or_404, redirect
from django.views.decorators.http import require_POST
from .models import Comment

@require_POST
def delete(request, id):
    # 根據 ID 獲取 Comment,若不存在則返回 404
    comment = get_object_or_404(Comment, id=id)
    # 刪除留言
    comment.delete()
    # 返回到 Resume 的詳細頁面
    return redirect("resumes:show", id=comment.resume.id)

函數解讀

  1. get_object_or_404: 確保傳入的 ID 有對應的 Comment,若不存在則返回 404 頁面。
  2. 刪除操作: 調用 comment.delete() 方法,將留言從資料庫中刪除。
  3. 轉址: 刪除後,使用 redirect 返回到該留言所屬的 Resume 詳細頁。

整合主路由

mysite 項目的主路由中引入 comments 應用的路由。

mysite/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('pages.urls')),
    path('resumes/', include('resumes.urls')),
    path('comments/', include('comments.urls')),
]

應用間的交互流程

留言刪除功能涉及兩個應用:resumescomments,它們需要協同工作以完成刪除操作。

流程概覽

  1. 模板發起刪除請求
    用戶在 resumes 應用的模板中點擊刪除按鈕。
    表單提交 POST 請求至 /comments/<comment_id>,傳遞需要刪除的留言 ID。
  2. comments 應用處理請求
    comments/views.py 中:
    • 捕獲傳入的留言 ID。
    • 刪除對應的 Comment 實例。
    • 轉址到 Resume 的詳細頁。
  3. 轉址至詳細頁
    使用 redirect 返回 Resume 的詳細頁,展示刪除後的留言列表。

交互流程的詳細步驟

模板發送請求

  • 所有留言顯示在 resumes 應用的模板中,並且為每條留言提供刪除按鈕。
  • 表單提交 POST 請求到 /comments/<comment_id>

範例模板代碼:

<ul>
    {% for comment in comments %}
    <li>
        {{ comment.content|linebreaksbr }}
        <form action="{% url 'comments:delete' comment.id %}" method="post">
            {% csrf_token %}
            <button type="submit"></button>
        </form>
        <small>{{ comment.created_at }}</small>
    </li>
    {% endfor %}
</ul>

comments 應用處理請求

  • comments/views.pydelete 函數負責處理刪除邏輯:
from django.shortcuts import get_object_or_404, redirect
from django.views.decorators.http import require_POST
from .models import Comment

@require_POST
def delete(request, id):
    # 根據 ID 獲取 Comment
    comment = get_object_or_404(Comment, id=id)
    # 刪除 Comment
    comment.delete()
    # 轉址回該 Comment 所屬的 Resume 詳細頁
    return redirect("resumes:show", id=comment.resume.id)
  • 核心代碼解讀
    1. get_object_or_404:確保提供的 ID 對應一條有效的 Comment,否則返回 404 錯誤。
    2. comment.delete():調用模型的刪除方法,將資料從資料庫中移除。
    3. redirect("resumes:show", id=comment.resume.id):通過外鍵反向引用 Resume,返回到該 Resume 的詳細頁。

3. 目錄結構與文件說明

以下是項目中與刪除留言功能相關的目錄結構及其作用:

mysite/
├── mysite/
   ├── urls.py          # 主路由,包含 resumes 和 comments 應用的路由

├── resumes/
   ├── templates/
      ├── resumes/
          ├── show.html  # 顯示 Resume 的詳細內容和留言列表
   ├── urls.py           # 配置 resumes 應用的路由,包括顯示 Resume 詳情

├── comments/
   ├── urls.py           # 定義刪除留言的路由
   ├── views.py          # 實現刪除功能的視圖邏輯
   ├── models.py         # 定義 Comment 模型,與 Resume 建立關聯

小結

透過本指南,我們完成了留言刪除功能的開發:

  1. 模板設計
    • 在模板中新增刪除按鈕,提交 POST 請求以觸發刪除操作。
  2. 路由配置
    • comments/urls.py 中配置刪除留言的路徑。
  3. 視圖實現
    • comments/views.py 中完成刪除邏輯,並使用 redirect 返回 Resume 的詳細頁。
  4. 應用交互
    • 確保 resumescomments 應用能順暢協作。

這種分層設計確保代碼的清晰與高可維護性,是 Django 框架開發的核心思想之一。

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *