【django】Form と ModelForm の違い

Django

djangoでアプリを作り始めるとよくFormとModelFormをそれぞれ見かけます。
この2つって何が違うのか、どっちを使う方がいいのか?と疑問に思ったので調べてみました。

結論としては、
モデルで作るフィールドのみ使うならModelForm。
モデルで作るフィールド以外を使う場合があるならFormをオススメします。

Form と ModelForm の違い

FormとModelFormの主な違いは2つだけです。
「データの保存方法」と「フィールド」の違いだけです。

データの保存方法

データの保存方法はModelFormがModelに紐付いたフォームであるため、データ登録が非常に簡単です。

・ModelForm
form = ModelForm(request.POST)
form.is_valid
form.save()

form.save()だけで入力データの登録が完了します。

一方、FormはModelに沿って入力データを一つずつを合わせていく必要があります。

・Form
form = Form(request.POST)
form.is_valid
#save()で保存する場合
c = Model(a = request.POST['a'], b = request.POST['b'])
c.save()

#create()で保存する場合
Model.objects.create(a = request.POST['a'], b = request.POST['b'])

Formはsave()とcreate()で保存を行いましたが、
どちらもrequest.POSTの要素を一つずつ取り出して保存を行います。

コードを書いて比較すると、ModelFormの方がスマートにデータ登録まで書くことができます。
ただModelのフィールド以外に追加するなどアレンジを効かせる場合はFormが有利になります。

記述量と記述場所の差

他の差としてはFormに関する記述量とFormを書く場所の差です。
ModelFormではFormの記述量をガクンと減らすことができます。
以下の例文は公式サイトからの例文を参考にしています。

ModelFormの場合

from django.db import models
from django.forms import ModelForm

TITLE_CHOICES = [
    ('MR', 'Mr.'),
    ('MRS', 'Mrs.'),
    ('MS', 'Ms.'),
]

class Author(models.Model):
    name = models.CharField(max_length=100)
    title = models.CharField(max_length=3, choices=TITLE_CHOICES)
    birth_date = models.DateField(blank=True, null=True)

    def __str__(self):
        return self.name

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ['name', 'title', 'birth_date']

ModelFormの場合は、Formをmodels.pyに入れて書けます。
Formのコードはmodelに紐づいているため、Metaの中にmodelとfieldsだけFormができます。

Formの場合

from django import forms

class AuthorForm(forms.Form):
    name = forms.CharField(max_length=100)
    title = forms.CharField(
        max_length=3,
        widget=forms.Select(choices=TITLE_CHOICES),
    )
    birth_date = forms.DateField(required=False)

Formの場合は、modelが紐づいていないため、一つずつフィールドと細かな項目を書く必要があります。

そのほかの差分

データの保存方法とFormの記述量、記述場所以外では大きな差はないです。

views.pyでの処理はデータの保存方法以外は同じ処理です。
バリデートもcleaned_dataも出力できます。

def sample(request):
    form = AuthorForm(request.POST)
    if form.is_valid:
        temp_data = form.cleaned_data
        #データの保存

どちらを使うかは自由ですが、ModelFormの方が簡単でスマートな気がします。

以上、お付き合いいただきありがとうございました。

タイトルとURLをコピーしました