djangoでアプリを作り始めるとよく「Form」と「ModelForm」をそれぞれ見かけます。
この2つって何が違うのか、どっちを使う方がいいのか?と悩んでいる方に向けて
「Form」と「ModelForm」の違いを解説します。
先に結論としては、
モデルで作るフィールドのみ使うなら、「ModelForm」
モデルで作るフィールド以外を使う場合があるなら「Form」をオススメします。
Form と ModelForm の違い
FormとModelFormの主な違いは2つだけです。
「データの保存方法」と「フィールド」の違いだけです。
データの保存方法
データの保存方法はModelFormがModelに紐付いたフォームであるため、データ登録が非常に簡単です。
例えば、以下のコードはそのデータの保存方法を示しています。
ModelFormに入れるデータはrequest.POSTに入っているとします。
・ModelForm
form = ModelForm(request.POST)
form.is_valid
form.save()
この3行の中の form.save() だけで入力データの登録が完了します。
一方、FormはModelに沿って入力データを一つずつを合わせていく必要があります。
これも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の方が簡単でスマートな気がします。
以上、お付き合いいただきありがとうございました。