Django CRUD 的 U(Update):資料更新功能完整指南
更新日期: 2024 年 11 月 23 日
本文為 Django 進階教學,第 8 篇:
- 理解 Django 中的相對路徑與絕對路徑
- Django URL 路徑設置|name 參數與命名空間(Namespace)
- Django 串接資料庫與模型建構:完整入門指南
- Django 模型遷移與資料庫同步完整指南
- 使用 Django ORM 將資料寫入資料庫:新手入門指南
- Django 實現 CRUD 的 C(Create):新增資料功能完整指南
- Django CRUD 的 R(Read):資料讀取與顯示功能指南
- Django CRUD 的 U(Update):資料更新功能完整指南 👈 所在位置
- Django CRUD 的 D(Delete):資料刪除功能完整指南
建議閱讀本文前,先閱讀完 Django 新手教學 系列文
在 Django 的 CRUD 操作中,U(Update) 是負責實現對資料修改的部分。
本指南詳細介紹如何實現資料更新功能,包括路由配置、視圖編寫、模板設計,並解釋 HTML 表單與 RESTful 設計的兼容解決方案。
專案目錄結構
完成更新功能後,專案目錄的結構如下:
mysite/
├── manage.py
├── mysite/
│ ├── settings.py # 專案配置文件
│ ├── urls.py # 主路由配置
│
├── resumes/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py # 定義 Resume 模型
│ ├── views.py # 定義新增、編輯和處理邏輯
│ ├── urls.py # 配置應用的路由
│ ├── templates/
│ ├── resumes/
│ ├── home.html # 顯示資料列表
│ ├── new.html # 新增資料表單
│ ├── show.html # 顯示單筆資料
│ ├── edit.html # 編輯資料表單
├── db.sqlite3 # SQLite 資料庫
資料更新功能的核心調整
實現更新功能需要修改以下幾個部分:
- 路由配置:新增編輯頁面的路由。
- 視圖邏輯:編寫
edit
函數,處理資料查詢與更新。 - 顯示單筆資料:在
show.html
中新增編輯資料的超連結。 - 編輯頁面模板:新增
edit.html
,實現用戶資料顯示與修改的功能。
HTML 表單無法支持 PUT 方法的解決方案
在 RESTful API 的設計中,更新操作通常使用 PUT 方法,以區分於新增操作的 POST 方法。
然而,HTML 原生表單僅支持 GET 和 POST 方法,因此需要採取以下解決方案來兼容 RESTful 設計:
解決策略
- 繼續使用 POST 方法:
- 透過表單的
method="POST"
提交資料。 - 在視圖函數中,檢查
request.method
,判斷是否為更新操作。
- 透過表單的
- 顯示原始資料:
- 在表單中使用
value
或標籤內容顯示原始資料,確保用戶能夠查看並修改現有內容。 - 例如,使用以下代碼將現有資料顯示於表單中:
- 在表單中使用
<input type="text" name="title" value="{{ resume.title }}" />
<textarea name="content">{{ resume.content }}</textarea>
- URL 設計符合 RESTful 原則:
- 在表單的
action
屬性中,指定更新操作的目標路徑:
- 在表單的
<form action="{% url 'resumes:edit' resume.id %}" method="POST">
- 將資源的唯一標識(如
id
)作為路徑參數傳遞。
完整表單範例
以下是修改後的 edit.html
範例:
{% extends "shared/layout.html" %}
{% block content %}
<h1>編輯 Resume</h1>
<form action="{% url 'resumes:edit' resume.id %}" method="POST">
{% csrf_token %}
title: <br />
<input type="text" name="title" value="{{ resume.title }}" /> <br />
skill: <br />
<input type="text" name="skill" value="{{ resume.skill }}" /> <br />
content: <br />
<textarea name="content">{{ resume.content }}</textarea> <br />
<button type="submit">更新</button>
</form>
{% endblock %}
配置路由
在 resumes/urls.py
中新增編輯頁面的路由:
from django.urls import path
from . import views
app_name = 'resumes'
urlpatterns = [
path("", views.home, name='list'), # 主頁,顯示所有資料
path("new/", views.new, name='nn'), # 新增資料頁面
path("<int:id>/", views.show, name="show"), # 單筆資料頁面
path("<int:id>/edit/", views.edit, name="edit"), # 編輯資料頁面
]
編寫視圖邏輯
在 resumes/views.py
中新增 edit
函數,處理以下操作:
- GET 請求:查詢指定
id
的資料,顯示於表單中。 - POST 請求:接收用戶提交的資料,更新至資料庫。
視圖代碼
from django.shortcuts import render, get_object_or_404, redirect
from .models import Resume
def edit(request, id):
# 查詢資料,若不存在返回 404
resume = get_object_or_404(Resume, id=id)
if request.method == "POST":
# 接收表單資料並更新資料庫
resume.title = request.POST["title"]
resume.skill = request.POST["skill"]
resume.content = request.POST["content"]
resume.save()
# 更新完成後跳轉回列表頁
return redirect("resumes:list")
# GET 請求時顯示原始資料
return render(
request,
"resumes/edit.html",
{"resume": resume}
)
顯示單筆資料並添加編輯連結
在 resumes/templates/resumes/show.html
中新增編輯資料的超連結:
{% extends "shared/layout.html" %}
{% block content %}
<h1>{{ resume.title }}</h1>
<h3>{{ resume.skill }}</h3>
<article>
<p>{{ resume.content }}</p>
</article>
<footer>
<a href="{% url 'resumes:edit' resume.id %}">編輯</a>
</footer>
{% endblock %}
功能測試與檢查
測試流程
- 訪問單筆資料頁面,例如:
http://localhost:8000/resumes/1/
。 - 點擊「編輯」按鈕,跳轉到編輯頁面:
http://localhost:8000/resumes/1/edit/
。 - 修改資料後提交表單,確認是否更新成功並跳轉回主頁。
小結
通過以上步驟,我們實現了 Django CRUD 的 U(Update)功能:
- 兼容 HTML 表單與 RESTful 設計:
- 繼續使用 POST 方法,並在視圖中根據請求類型進行判斷。
- 顯示原始資料:
- 在表單中填入現有資料,提供用戶友好的編輯體驗。
- 路由與視圖設計:
- 路徑設計符合 RESTful 規範,視圖邏輯清晰。
- 安全性保障:
- 使用 CSRF 保護表單,避免跨站攻擊。
該功能為後續的資料操作(如刪除資料)提供了良好的基礎,並遵循業界標準提升系統設計的規範性與可維護性!