Django Forms的強大特性之一是 驗證。它會在用戶將數據發送到服務器之前自動檢查,從而保證安全性和準確性。本文將探討Django Forms的驗證機制及其自定義的方法。

1. 基本驗證

展示Django Forms驗證工作流程的圖示,包括表單提交、字段驗證和錯誤處理等關鍵步驟

1.1 什麼是驗證?

Django Forms確認數據是否符合表單字段的要求,這個過程包括由表單提供的基本驗證以及開發者自定義的驗證。

基本驗證範例
from django import forms

class RegistrationForm(forms.Form):
    username = forms.CharField(max_length=30, required=True)
    email = forms.EmailField(required=True)
    password = forms.CharField(widget=forms.PasswordInput, required=True)
  • username: 最多30個字元的限制。
  • email: 驗證是否為電子郵件格式。
  • password: 必須輸入,並使用密碼輸入框。

1.2 數據驗證流程

Django Forms將驗證後的數據存儲到 cleaned_data 中,這將以字典格式返回,其中字段名稱作為鍵。

  • 如果數據驗證失敗,錯誤信息將作為字典存儲在 form.errors 屬性中。每個字段名稱作為鍵,該字段的錯誤信息作為值。
  1. 用戶輸入數據並提交表單。
  2. Django調用 is_valid() 方法來驗證數據。
  3. 如果數據有效,則存儲在 cleaned_data 中,否則將添加錯誤信息。
數據驗證流程範例
form = RegistrationForm(request.POST)
if form.is_valid():
    username = form.cleaned_data['username']
    email = form.cleaned_data['email']
    password = form.cleaned_data['password']
else:
    print(form.errors)  # 驗證失敗時輸出錯誤

2. 字段級驗證自定義

2.1 clean_fieldname() 方法

要自定義特定字段的驗證,需要定義 clean_fieldname() 方法。

範例:檢查用戶名重複
class RegistrationForm(forms.Form):
    username = forms.CharField(max_length=30)

    def clean_username(self):
        username = self.cleaned_data['username']
        if username.lower() == 'admin':
            raise forms.ValidationError("'admin'不能用作用戶名。")
        return username

工作原理: clean_username() 方法檢查 username 字段的有效性,若有問題則拋出異常。

3. 整個表單的驗證

3.1 clean() 方法

當需要基於整個表單數據進行驗證時,覆蓋 clean() 方法。

範例:密碼確認
class PasswordChangeForm(forms.Form):
    new_password = forms.CharField(widget=forms.PasswordInput)
    confirm_password = forms.CharField(widget=forms.PasswordInput)

    def clean(self):
        cleaned_data = super().clean()
        password = cleaned_data.get("new_password")
        confirm_password = cleaned_data.get("confirm_password")

        if password != confirm_password:
            raise forms.ValidationError("密碼不一致。")

        return cleaned_data

用途: 當需要驗證多個字段的相互關係時使用。

4. 錯誤信息自定義

Django Forms提供基本的錯誤信息,但可以自定義以提供更友好的信息。

4.1 修改字段錯誤信息

範例:指定字段錯誤信息
class CustomErrorForm(forms.Form):
    email = forms.EmailField(
        error_messages={
            'required': "請輸入電子郵件。",
            'invalid': "請輸入有效的電子郵件地址。"
        }
    )

4.2 處理整個表單的錯誤

範例:密碼驗證錯誤信息
class LoginForm(forms.Form):
    username = forms.CharField(max_length=30)
    password = forms.CharField(widget=forms.PasswordInput)

    def clean(self):
        cleaned_data = super().clean()
        username = cleaned_data.get('username')
        password = cleaned_data.get('password')

        # 添加用戶驗證邏輯
        if not authenticate(username=username, password=password):
            raise forms.ValidationError("用戶名或密碼不正確。")

5. 實戰範例:複合驗證

5.1 註冊表單實現

表單定義
class SignupForm(forms.Form):
    username = forms.CharField(max_length=30)
    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)
    confirm_password = forms.CharField(widget=forms.PasswordInput)

    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError("該用戶名已被使用。")
        return username

    def clean(self):
        cleaned_data = super().clean()
        password = cleaned_data.get('password')
        confirm_password = cleaned_data.get('confirm_password')

        if password != confirm_password:
            raise forms.ValidationError("密碼不一致。")
        return cleaned_data
視圖定義
from django.shortcuts import render, redirect
from .forms import SignupForm

def signup_view(request):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            User.objects.create_user(
                username=form.cleaned_data['username'],
                email=form.cleaned_data['email'],
                password=form.cleaned_data['password']
            )
            return redirect('login')
    else:
        form = SignupForm()
    return render(request, 'signup.html', {'form': form})

6. 結論

Django Forms的驗證是加強數據輸入準確性和安全性的核心功能。除了提供的基本驗證功能之外,還可以根據項目需求自定義驗證。在下一篇文章中,我們將探討 Django Forms和CSS的表單樣式