【django】Form と ModelForm の違い

スポンサーリンク
Django

djangoでアプリを作り始めるとよく「Form」「ModelForm」をそれぞれ見かけます。

この2つって何が違うのか、どっちを使う方がいいのか?と悩んでいる方に向けて

「Form」「ModelForm」の違いを解説します。

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

Form と ModelForm の違い

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

データの保存方法

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

例えば、以下のコードはそのデータの保存方法を示しています。
ModelFormに入れるデータはrequest.POSTに入っているとします。

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

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

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

これもFormに入れるデータはrequest.POSTに入っているとします。
途中から一つずつ入力データを取り出す必要があります。

・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を記述量と書く場所の差です。

ModelFormではFormの記述量をガクンと減らすことができます。
これもmodelと紐づいているからですね。

以下の例文は公式サイトからの例文を参考にしています。

ModelFormの場合のmodels.py

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の場合は、models.pyにModelFormを入れて書くことができます。

具体的には一番下のAuthorFormクラスがModelFormです。

Formのコードはmodelに紐づいているため、Metaの中にmodelとfieldsだけModelFormができます

Formの場合のforms.py

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が紐づいていないため、models.pyには書くことができず

forms.pyに一つずつフィールドと細かな項目を書く必要があります。

そのほかの差分

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

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

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

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

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

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