Djangoでは forms.Formforms.ModelForm という2つの主要なフォームクラスを提供しています。この投稿では、2つのクラスの違いとそれぞれの使用ケースを通じて、どの状況でどのフォームを選ぶべきかを説明します。

1. forms.Formforms.ModelForm の概要

Comparison between forms.Form and forms.ModelForm in Django, highlighting differences like Model Association and Data Handling

1.1 forms.Formとは?

  • 独立したフォームクラス: Djangoモデルとは無関係に動作し、必要なデータを手動で定義できます。
  • 主な用途: ユーザーからの入力を受け取って単純に検証するか、モデルと直接関係しないデータを処理する際に使用されます。
例:ユーザーフィードバックフォーム
from django import forms

class FeedbackForm(forms.Form):
    name = forms.CharField(max_length=50, label="Your Name")
    email = forms.EmailField(label="Your Email")
    message = forms.CharField(widget=forms.Textarea, label="Your Feedback")

1.2 forms.ModelFormとは?

  • モデルに関連付けられたフォームクラス: Djangoモデルと直接的に関連しており、データベースとの対話が自動化されます。
  • 主な用途: モデルインスタンスを作成、更新または、データベースに保存するためのデータを受け取る際に使用されます。
例:ブログ記事作成フォーム
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'content']

2. 主な違いの比較

区分 forms.Form forms.ModelForm
モデルとの関連 モデルとは無関係 モデルと直接関連
データ処理 データを検証後に手動で保存 データを自動で保存 (form.save() メソッド使用)
フィールド定義の方法 すべてのフィールドを明示的に定義 モデルのフィールドを自動でフォームフィールドに変換
使用用途 独立したデータ処理やユーザー入力フォーム データベース操作と関連したフォーム
柔軟性 自由にフィールドを構成可能 モデルフィールドに依存

3. 使用ケース

3.1 forms.Form 使用ケース

  1. モデルと無関係なデータ処理: 例: 検索フォーム、ログインフォーム、パスワードリセットフォーム。
検索フォームの例
class SearchForm(forms.Form):
    query = forms.CharField(max_length=100, label="Search")
  1. 複雑なユーザー入力の処理: 例: 入力フィールドがモデルに直接保存されない場合。
パスワード変更フォームの例
class PasswordChangeForm(forms.Form):
    old_password = forms.CharField(widget=forms.PasswordInput, label="Old Password")
    new_password = forms.CharField(widget=forms.PasswordInput, label="New Password")
    confirm_password = forms.CharField(widget=forms.PasswordInput, label="Confirm Password")

    def clean(self):
        cleaned_data = super().clean()
        new_password = cleaned_data.get("new_password")
        confirm_password = cleaned_data.get("confirm_password")
        if new_password != confirm_password:
            raise forms.ValidationError("Passwords do not match.")

3.2 forms.ModelForm 使用ケース

  1. モデルオブジェクトの生成および更新: 例: ブログ記事作成、コメント作成、ユーザープロフィールの修正。
コメント作成フォームの例
class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['author', 'text']
  1. モデルに基づくデータ入力: 例: 既存データを修正またはデータベースに保存する際。

4. フォームの動作方式の比較

4.1 データ検証

  • forms.Form: 手動でフィールドと検証ロジックを定義。
  • forms.ModelForm: モデルフィールドに定義された検証ルールを自動で使用。
例:モデルフィールドの検証
class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ['name', 'price']
  • price フィールドはモデルに定義された制約 (max_digits, decimal_places) を自動で検証します。

4.2 データ保存

  • forms.Form: cleaned_data を使用してデータを処理。
  • forms.ModelForm: save() メソッドでデータを自動保存。
forms.Form データ保存例
form = FeedbackForm(request.POST)
if form.is_valid():
    feedback = Feedback(
        name=form.cleaned_data['name'],
        email=form.cleaned_data['email'],
        message=form.cleaned_data['message']
    )
    feedback.save()
forms.ModelForm データ保存例
form = PostForm(request.POST)
if form.is_valid():
    form.save()

5. どのフォームを選べばいいのか?

  1. モデルに関連する作業: データベースと直接相互作用する必要がある場合は forms.ModelForm を使用するのが適切です。
  2. モデルに無関係な作業: 独立したデータ検証やユーザー入力処理が必要な場合は forms.Form を使用してください。

結論

forms.Formforms.ModelForm は、Djangoでデータ入力と検証を処理するための2つの強力なツールです。これらのクラスは用途や特徴が異なるため、状況に応じたフォームを選ぶことが重要です。次回の投稿では フォームフィールドとウィジェット について詳しく見ていきます。