文章

Django - 表單與驗證

今天我們將學習如何處理用戶的表單輸入與數據驗證,這是任何網頁應用程式中不可或缺的一部分。Django 提供了強大的表單工具來輕鬆實現表單的處理與驗證。


課程目標

  • 瞭解 Django 表單的作用與結構。
  • 學習如何使用 forms 處理用戶輸入。
  • 掌握表單數據驗證的基本方法。
  • 設計並實現一個帶驗證功能的簡單表單。

課程內容

1. 表單概述

1.1 表單的作用

  • 表單用於收集用戶輸入並將其發送到服務器處理。
  • 包括 HTML 的輸入元件以及後端的數據驗證與處理邏輯。

1.2 Django 表單工具

Django 提供以下工具來處理表單:

  • Django Forms:自定義表單,用於處理與驗證非模型數據。
  • Model Forms:基於模型的表單,用於快速創建與模型相關的表單。

2. 自訂表單

2.1 建立表單類別

在應用目錄下的 forms.py 中定義表單:

1
2
3
4
5
6
7
8
9
10
11
12
13
from django import forms

class BookForm(forms.Form):
    title = forms.CharField(max_length=200, label="書名")
    author = forms.CharField(max_length=100, label="作者")
    published_date = forms.DateField(label="出版日期", widget=forms.DateInput(attrs={'type': 'date'}))
    price = forms.DecimalField(max_digits=10, decimal_places=2, label="價格")

    def clean_price(self):
        price = self.cleaned_data.get('price')
        if price <= 0:
            raise forms.ValidationError("價格必須大於 0!")
        return price

2.2 處理表單數據

views.py 中添加處理邏輯:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from django.shortcuts import render
from .forms import BookForm

def add_book(request):
    if request.method == 'POST':
        form = BookForm(request.POST)
        if form.is_valid():
            # 獲取表單數據
            title = form.cleaned_data['title']
            author = form.cleaned_data['author']
            published_date = form.cleaned_data['published_date']
            price = form.cleaned_data['price']
            # 保存到資料庫(需先建立模型)
            from .models import Book
            Book.objects.create(title=title, author=author, published_date=published_date, price=price)
            return render(request, 'add_book_success.html')
    else:
        form = BookForm()

    return render(request, 'add_book.html', {'form': form})

3. 基於模型的表單

3.1 建立 ModelForm

基於模型的表單可以簡化表單的創建:

1
2
3
4
5
6
7
from django import forms
from .models import Book

class BookModelForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['title', 'author', 'published_date', 'price']

3.2 使用 ModelForm

在視圖中使用:

1
2
3
4
5
6
7
8
9
10
11
12
from .forms import BookModelForm

def add_book(request):
    if request.method == 'POST':
        form = BookModelForm(request.POST)
        if form.is_valid():
            form.save()  # 自動保存到資料庫
            return render(request, 'add_book_success.html')
    else:
        form = BookModelForm()

    return render(request, 'add_book.html', {'form': form})

4. 表單模板渲染

4.1 渲染表單

在模板中使用 {{ form.as_p }} 簡化表單渲染:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!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>

4.2 自訂表單樣式

透過 HTML 和 CSS 自訂表單外觀:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<form method="post" class="form-container">
  {% csrf_token %}
  <div class="form-group">
    <label for="id_title">書名:</label>
    {{ form.title }}
  </div>
  <div class="form-group">
    <label for="id_author">作者:</label>
    {{ form.author }}
  </div>
  <div class="form-group">
    <label for="id_published_date">出版日期:</label>
    {{ form.published_date }}
  </div>
  <div class="form-group">
    <label for="id_price">價格:</label>
    {{ form.price }}
  </div>
  <button type="submit" class="btn btn-primary">提交</button>
</form>

5. 表單驗證

5.1 使用內建驗證

Django 提供豐富的內建驗證功能,如:

  • required:確保欄位不為空。
  • max_length:限制字串長度。
  • validators:使用自訂的驗證器。

5.2 自訂驗證方法

在表單類別中新增驗證方法:

1
2
3
4
5
def clean_author(self):
    author = self.cleaned_data.get('author')
    if len(author) < 3:
        raise forms.ValidationError("作者姓名必須超過 3 個字元!")
    return author

5.3 驗證提示訊息

在模板中顯示錯誤訊息:

1
2
3
4
5
6
7
8
9
{% if form.errors %}
<div class="error-messages">
  <ul>
    {% for field, errors in form.errors.items %}
    <li>{{ field }}: {{ errors|join:", " }}</li>
    {% endfor %}
  </ul>
</div>
{% endif %}

6. 本日總結

  • 理解了 Django 表單的作用與基本結構。
  • 學習了如何使用 forms 處理用戶輸入並進行數據驗證。
  • 掌握了基於模型的表單創建方式,並使用表單完成數據保存。

作業

  1. 創建一個新的表單,讓用戶輸入書籍分類並保存到資料庫。
  2. 修改模板,為表單添加一些額外樣式(如錯誤提示的紅色字體)。
  3. 為表單新增驗證邏輯,例如檢查輸入的日期是否為過去的日期。

本文章以 CC BY 4.0 授權