在現代 Web 開發中,Django 以其高效、強大的功能成為開發者的首選框架之一。今天,我們將深入探討 Django 的應用開發,從建立簡單的網頁應用程序、處理資料庫與表單,到加強資料庫的使用,實現增刪查改(CRUD)功能。通過本課程,你將能夠構建一個功能完整的 Django 應用,掌握核心開發技巧。
首先,確保你已經安裝了 Python 和 pip。接下來,建議使用虛擬環境來管理專案的依賴。
# 創建虛擬環境(可選)
python -m venv myenv
# 啟動虛擬環境
# Windows
myenv\Scripts\activate
# macOS/Linux
source myenv/bin/activate
# 安裝 Django
pip install django
創建一個新的 Django 專案,並在其中建立一個應用。
# 創建專案
django-admin startproject myproject
# 進入專案目錄
cd myproject
# 創建應用
python manage.py startapp myapp
在 myproject/settings.py
中,將新創建的應用加入 INSTALLED_APPS
列表:
# myproject/settings.py
INSTALLED_APPS = [
...
'myapp',
]
在 myapp/models.py
中,定義一個簡單的資料模型。例如,一個用來管理書籍資訊的模型:
# myapp/models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200) # 書名
author = models.CharField(max_length=100) # 作者
published_date = models.DateField() # 出版日期
isbn = models.CharField(max_length=13) # ISBN 編號
def __str__(self):
return self.title
# 創建遷移檔案
python manage.py makemigrations
# 應用遷移到資料庫
python manage.py migrate
在 myapp/admin.py
中,註冊 Book
模型到 Django 管理後台:
# myapp/admin.py
from django.contrib import admin
from .models import Book
admin.site.register(Book)
接下來,創建一個管理員帳號,並啟動開發伺服器:
# 創建管理員帳號
python manage.py createsuperuser
# 啟動伺服器
python manage.py runserver
打開瀏覽器,訪問 http://127.0.0.1:8000/admin/
,使用剛剛創建的管理員帳號登錄,你將看到 Book
模型,並可以在這裡添加、修改和刪除書籍資訊。
為了讓使用者能夠通過網頁界面添加或編輯書籍資訊,我們需要創建表單。在 myapp/forms.py
中定義一個表單:
# myapp/forms.py
from django import forms
from .models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['title', 'author', 'published_date', 'isbn']
在 myapp/views.py
中,創建視圖來處理表單的顯示和提交:
# myapp/views.py
from django.shortcuts import render, redirect
from .forms import BookForm
from .models import Book
def book_list(request):
books = Book.objects.all()
return render(request, 'book_list.html', {'books': books})
def add_book(request):
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save()
return redirect('book_list')
else:
form = BookForm()
return render(request, 'add_book.html', {'form': form})
接著,創建模板文件:
myapp
目錄下創建 templates
資料夾。templates
資料夾內創建 book_list.html
和 add_book.html
。book_list.html
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>書籍列表</title>
</head>
<body>
<h1>書籍列表</h1>
<a href="{% url 'add_book' %}">新增書籍</a>
<ul>
{% for book in books %}
<li>{{ book.title }} - {{ book.author }} ({{ book.published_date }})</li>
{% empty %}
<li>尚無書籍資料。</li>
{% endfor %}
</ul>
</body>
</html>
add_book.html
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>新增書籍</title>
</head>
<body>
<h1>新增書籍</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">提交</button>
</form>
<a href="{% url 'book_list' %}">返回書籍列表</a>
</body>
</html>
在 myapp
目錄下創建 urls.py
,並定義應用的 URL 路由:
# myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.book_list, name='book_list'),
path('add/', views.add_book, name='add_book'),
]
然後,在主項目的 urls.py
中包含應用的路由:
# myproject/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')),
]
啟動開發伺服器,訪問 http://127.0.0.1:8000/
,你將看到書籍列表頁面。點擊「新增書籍」連結,可以填寫表單並新增書籍資訊。提交後,將自動返回書籍列表,並顯示新增的書籍。
在上一節中,我們建立了一個基本的 Django 應用,並實現了資料的讀取和新增功能。今天,我們將進一步加強資料庫的使用,實現資料的刪除和修改功能,全面掌握 CRUD(Create, Read, Update, Delete)操作。
在 myapp/views.py
中,添加編輯和刪除書籍的視圖:
# myapp/views.py
from django.shortcuts import render, redirect, get_object_or_404
from .forms import BookForm
from .models import Book
def book_list(request):
books = Book.objects.all()
return render(request, 'book_list.html', {'books': books})
def add_book(request):
if request.method == 'POST':
form = BookForm(request.POST)
if form.is_valid():
form.save()
return redirect('book_list')
else:
form = BookForm()
return render(request, 'add_book.html', {'form': form})
def edit_book(request, pk):
book = get_object_or_404(Book, pk=pk)
if request.method == 'POST':
form = BookForm(request.POST, instance=book)
if form.is_valid():
form.save()
return redirect('book_list')
else:
form = BookForm(instance=book)
return render(request, 'edit_book.html', {'form': form, 'book': book})
def delete_book(request, pk):
book = get_object_or_404(Book, pk=pk)
if request.method == 'POST':
book.delete()
return redirect('book_list')
return render(request, 'delete_book.html', {'book': book})
在 templates
資料夾中,創建 edit_book.html
和 delete_book.html
。
edit_book.html
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>編輯書籍</title>
</head>
<body>
<h1>編輯書籍:{{ book.title }}</h1>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">更新</button>
</form>
<a href="{% url 'book_list' %}">返回書籍列表</a>
</body>
</html>
delete_book.html
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>刪除書籍</title>
</head>
<body>
<h1>確定刪除書籍:{{ book.title }}?</h1>
<form method="POST">
{% csrf_token %}
<button type="submit">確定刪除</button>
</form>
<a href="{% url 'book_list' %}">取消</a>
</body>
</html>
在 myapp/urls.py
中,添加編輯和刪除的路由:
# myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.book_list, name='book_list'),
path('add/', views.add_book, name='add_book'),
path('edit/<int:pk>/', views.edit_book, name='edit_book'),
path('delete/<int:pk>/', views.delete_book, name='delete_book'),
]
在 book_list.html
中,為每本書添加編輯和刪除的連結:
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>書籍列表</title>
</head>
<body>
<h1>書籍列表</h1>
<a href="{% url 'add_book' %}">新增書籍</a>
<ul>
{% for book in books %}
<li>
{{ book.title }} - {{ book.author }} ({{ book.published_date }})
<a href="{% url 'edit_book' book.pk %}">編輯</a>
<a href="{% url 'delete_book' book.pk %}">刪除</a>
</li>
{% empty %}
<li>尚無書籍資料。</li>
{% endfor %}
</ul>
</body>
</html>
重新啟動開發伺服器,並在瀏覽器中訪問 http://127.0.0.1:8000/
。你應該能夠:
Django 提供了強大的 ORM,讓開發者能夠通過 Python 代碼來操作資料庫,而無需撰寫 SQL 語句。ORM 提供了對資料庫模型的抽象,使得資料操作更加直觀和安全。
讓我們擴展 Book
模型,添加更多屬性,並建立模型之間的關聯。例如,添加一個 Publisher
模型,並與 Book
模型建立一對多關係:
# myapp/models.py
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=200) # 出版社名稱
address = models.CharField(max_length=300) # 出版社地址
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=200) # 書名
author = models.CharField(max_length=100) # 作者
published_date = models.DateField() # 出版日期
isbn = models.CharField(max_length=13) # ISBN 編號
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) # 出版社
def __str__(self):
return self.title
# 創建遷移檔案
python manage.py makemigrations
# 應用遷移到資料庫
python manage.py migrate
在 myapp/admin.py
中,註冊 Publisher
模型:
# myapp/admin.py
from django.contrib import admin
from .models import Book, Publisher
admin.site.register(Book)
admin.site.register(Publisher)
在 myapp/forms.py
中,更新 BookForm
以包含 publisher
欄位:
# myapp/forms.py
from django import forms
from .models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['title', 'author', 'published_date', 'isbn', 'publisher']
在 book_list.html
中,顯示出版社名稱:
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>書籍列表</title>
</head>
<body>
<h1>書籍列表</h1>
<a href="{% url 'add_book' %}">新增書籍</a>
<ul>
{% for book in books %}
<li>
{{ book.title }} - {{ book.author }} - {{ book.publisher.name }} ({{ book.published_date }})
<a href="{% url 'edit_book' book.pk %}">編輯</a>
<a href="{% url 'delete_book' book.pk %}">刪除</a>
</li>
{% empty %}
<li>尚無書籍資料。</li>
{% endfor %}
</ul>
</body>
</html>
讓我們實現以下功能:
範例:根據出版社篩選書籍
在 views.py
中,修改 book_list
視圖以支持篩選:
# myapp/views.py
def book_list(request):
publisher_id = request.GET.get('publisher')
if publisher_id:
books = Book.objects.filter(publisher_id=publisher_id)
else:
books = Book.objects.all()
publishers = Publisher.objects.all()
return render(request, 'book_list.html', {'books': books, 'publishers': publishers})
在 book_list.html
中,添加一個篩選表單:
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>書籍列表</title>
</head>
<body>
<h1>書籍列表</h1>
<a href="{% url 'add_book' %}">新增書籍</a>
<form method="GET">
<label for="publisher">篩選出版社:</label>
<select name="publisher" id="publisher">
<option value="">全部</option>
{% for publisher in publishers %}
<option value="{{ publisher.id }}">{{ publisher.name }}</option>
{% endfor %}
</select>
<button type="submit">篩選</button>
</form>
<ul>
{% for book in books %}
<li>
{{ book.title }} - {{ book.author }} - {{ book.publisher.name }} ({{ book.published_date }})
<a href="{% url 'edit_book' book.pk %}">編輯</a>
<a href="{% url 'delete_book' book.pk %}">刪除</a>
</li>
{% empty %}
<li>尚無書籍資料。</li>
{% endfor %}
</ul>
</body>
</html>
為了實現一次性刪除多本書籍,我們需要在模板中添加多選框,並在視圖中處理刪除邏輯。
更新 book_list.html
:
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>書籍列表</title>
</head>
<body>
<h1>書籍列表</h1>
<a href="{% url 'add_book' %}">新增書籍</a>
<form method="GET">
<label for="publisher">篩選