iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Python

Python探索之旅:從基礎到實踐系列 第 22

DAY 22: 征服 Django——從零到全能的資料庫與 CRUD 應用開發之旅

  • 分享至 

  • xImage
  •  

在現代 Web 開發中,Django 以其高效、強大的功能成為開發者的首選框架之一。今天,我們將深入探討 Django 的應用開發,從建立簡單的網頁應用程序、處理資料庫與表單,到加強資料庫的使用,實現增刪查改(CRUD)功能。通過本課程,你將能夠構建一個功能完整的 Django 應用,掌握核心開發技巧。


一、建立簡單的網頁應用程序:處理資料庫和表單

1. 安裝與設定 Django 環境

首先,確保你已經安裝了 Python 和 pip。接下來,建議使用虛擬環境來管理專案的依賴。

# 創建虛擬環境(可選)
python -m venv myenv

# 啟動虛擬環境
# Windows
myenv\Scripts\activate
# macOS/Linux
source myenv/bin/activate

# 安裝 Django
pip install django
2. 創建 Django 專案與應用

創建一個新的 Django 專案,並在其中建立一個應用。

# 創建專案
django-admin startproject myproject

# 進入專案目錄
cd myproject

# 創建應用
python manage.py startapp myapp
3. 配置應用

myproject/settings.py 中,將新創建的應用加入 INSTALLED_APPS 列表:

# myproject/settings.py

INSTALLED_APPS = [
    ...
    'myapp',
]
4. 定義資料模型(Models)

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
5. 創建並應用資料庫遷移
# 創建遷移檔案
python manage.py makemigrations

# 應用遷移到資料庫
python manage.py migrate
6. 設定管理後台

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 模型,並可以在這裡添加、修改和刪除書籍資訊。

7. 創建表單(Forms)

為了讓使用者能夠通過網頁界面添加或編輯書籍資訊,我們需要創建表單。在 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']
8. 設定視圖(Views)與模板(Templates)

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})

接著,創建模板文件:

  1. myapp 目錄下創建 templates 資料夾。
  2. templates 資料夾內創建 book_list.htmladd_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>
9. 設定 URL 路由

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')),
]
10. 測試應用

啟動開發伺服器,訪問 http://127.0.0.1:8000/,你將看到書籍列表頁面。點擊「新增書籍」連結,可以填寫表單並新增書籍資訊。提交後,將自動返回書籍列表,並顯示新增的書籍。


二、Django 應用開發(二):加強資料庫的使用,實現增刪查改功能

在上一節中,我們建立了一個基本的 Django 應用,並實現了資料的讀取和新增功能。今天,我們將進一步加強資料庫的使用,實現資料的刪除和修改功能,全面掌握 CRUD(Create, Read, Update, Delete)操作。

1. 更新視圖(Views)以支持編輯和刪除

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})
2. 創建編輯與刪除的模板

templates 資料夾中,創建 edit_book.htmldelete_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>
3. 更新 URL 路由

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'),
]
4. 更新模板以支持編輯和刪除連結

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>
5. 測試 CRUD 功能

重新啟動開發伺服器,並在瀏覽器中訪問 http://127.0.0.1:8000/。你應該能夠:

  • 新增 書籍:點擊「新增書籍」連結,填寫表單後提交。
  • 編輯 書籍:在書籍列表中,點擊「編輯」連結,修改書籍資訊後提交。
  • 刪除 書籍:在書籍列表中,點擊「刪除」連結,確認刪除後,該書籍將從列表中移除。

三、深入資料庫的使用:實現增刪查改功能

1. 理解 Django ORM(Object-Relational Mapping)

Django 提供了強大的 ORM,讓開發者能夠通過 Python 代碼來操作資料庫,而無需撰寫 SQL 語句。ORM 提供了對資料庫模型的抽象,使得資料操作更加直觀和安全。

2. 定義更複雜的模型

讓我們擴展 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
3. 應用遷移並更新管理後台
# 創建遷移檔案
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)
4. 更新表單以處理關聯模型

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']
5. 編輯視圖與模板以支持關聯資料

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>
6. 實現更複雜的 CRUD 操作

讓我們實現以下功能:

  • 篩選書籍:根據出版社或作者篩選書籍。
  • 批量刪除:一次性刪除多本書籍。
  • 彈性查詢:使用查詢參數進行動態搜尋。

範例:根據出版社篩選書籍

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>
7. 實現批量刪除功能

為了實現一次性刪除多本書籍,我們需要在模板中添加多選框,並在視圖中處理刪除邏輯。

更新 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">篩選

上一篇
DAY 21: 掌握 Web 框架——從 Flask 入門到 Django 初探
下一篇
DAY 23: 解鎖 Django 中介軟體與管理介面——打造高效應用邏輯的秘密武器
系列文
Python探索之旅:從基礎到實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言