(最終更新月:2022年3月)
✔このような方へ向けて書かれた記事となります
「ModelFormって何?Formクラスと何が違うの?」
「ModelFormの書き方、使い方が知りたい!」
「ModelFormを使った具体例が見てみたい。」
✔当記事を通じてお伝えすること
- ModelFormとは?Formクラスと使い分けるには?
- ModelFormの基本〜書き方編
- ModelFormの具体例をお見せします
【著者プロフィール】

当ブログを通じて、下記アプリの作り方、コード等を公開、解説しています
☆日報アプリ「D-Repo」(デモ版)→こちら
☆便利ツールアプリ「Tool Station」→こちら
✔初期費用ゼロ/月9,800円でWebデザインが学べる
デザインを習得するためには、客観的なフィードバックと改善が不可欠です。
以下の記事ではこんなWebデザインスクールをご紹介しています。
- 初期費用ゼロで、月々9,800円のみ
- オンラインで、教材が使い放題
- コンテストや実務案件にチャレンジして報酬もGETできる
デザナルはトップデザイナーからレビューがもらえる、格安のWebデザインスクールです。
詳細をまとめた記事もございますので、ぜひご覧ください。
ModelFormとは?Formクラスとの違いは?

ModelFormとは?
ModelFormとは、既存のモデルと連携されたフォームを作成するためのフォームクラスです。
DjangoのFormクラス同様、formsモジュール内に存在します。
from django.forms import ModelForm
Formクラスとの違いを具体的に見ていくことで理解を深めていきましょう。
Formクラスとの違い|ModelFormのメリット・デメリット
Formクラスの構成
from django import forms
class TestForm(forms.Form):
field1 = forms.CharField(max_length=255)
field2 = forms.IntegerField()
fields3 = ....
....
特に既存のモデルとは関係がなく、必要なフィールドを全て記述していきます。
ModelFormクラスの構成
from django import forms
from .models import NippoModel
class TestModelForm(forms.ModelForm):
class Meta:
model = NippoModel
fields = "__all__"
ModelForm内で紐付けたいモデルとそのフィールドを指定します。
ModelFormクラスのメリット
- フィールド数に関わらず、必要なコードは数行だけ
- 保存や編集の際も連動して動くため、余計なメソッドの記述が不要
ModelFormクラスのデメリット
- 紐付けるモデルが必要
- 自由度が少し低い
対象のモデルが決まっていて、データを保存、編集したい場合はModelFormが適しています。
次章で書き方を見ていきます。
ModelFormの基本 〜 書き方編

ModelFormの書き方
構成としては下記の通りとなります。
from django import forms
from .models import モデル名
class フォームクラス名(forms.ModelForm):
class Meta:
model = モデル名
fileds = "__all__" #表示するフィールドを指定します。
ポイントは3つです。
- 継承したクラス内でMetaクラスを定義
- 「model」変数で保存・編集するモデルクラスを指定
- 「fields」変数で使用するフィールドを指定
特に、3.「fields」には下記の通りフィールドを指定します。
#フィールド全て
fields = "__all__"
#フィールドの一部
fields = ["フィールド1", "フィールド2"]
#一部のフィールドを除く
exclude = "user"
ビューの書き方
ビューの書き方としては基本はフォームクラスと同様です。
ただし、form_validメソッドは割愛することも可能です。
from django.views.generic.edit import CreateView
from .forms import フォームクラス名
class ビュークラス名(CreateView):
template_name = テンプレートパス
form_class = フォームクラス名
success_url = URLパス
「Formクラスの書き方を知りたい!」という方はこちらをご覧ください。
ModelFormの使い方〜具体例をお見せします

こちらのモデルを使用して、①CreateView②UpdateViewを作っていきます。
models.py
class NippoModel(models.Model):
title = models.CharField(max_length=100, verbose_name="タイトル")
content = models.TextField(max_length=1000, verbose_name="内容")
public = models.BooleanField(default=False, verbose_name="公開する")
slug = models.SlugField(max_length=20, unique=True, default=slug_maker)
CreateViewの作成
forms.py
from django import forms
from .models import NippoModel
class NippoModelForm(forms.ModelForm):
class Meta:
model = NippoModel
fields = "__all__"
def __init__(self, *args, **kwargs):
for field in self.base_fields.values():
field.widget.attrs["class"] = "form-control"
super().__init__(*args, **kwargs)
※__init__関数の箇所では、Bootstrapの「form-control」クラスを各フィールドに適用するためのものです。必ず必要なものではありません。
views.py
from django.views.generic.edit import CreateView
class NippoCreateFormView(CreateView):
template_name = "nippo/nippo-formclass.html"
form_class = NippoModelForm
success_url = reverse_lazy("nippo-list")
ポイントは下記の通りです。
- CreateViewのインポート
- 「template_name」「form_class」「success_url」変数へ値を格納
- form_valid関数は不要
html
{% extends 'base.html' %}
{% block content %}
<div class="container my-3" style="max-width:700px;">
<div class="text-center my-3">
<h2>新しく日報を作成</h2>
</div>
<form method="POST"> {% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary form-control" type="submit">登録</button>
</form>
</div>
{% endblock %}
urls.py
from django.urls import path
from .views import NippoCreateView
urlpatterns = [
path("create/", NippoCreateView.as_view(), name="nippo-create"),
]
UpdateViewの作成
同じModelFormを使用します。ModelForm以外のコードを見ていきましょう。
views.py
class NippoUpdateFormView(UpdateView):
template_name = "nippo/nippo-formclass.html"
model = NippoModel
form_class = NippoModelForm
success_url = reverse_lazy("nippo-list")
html
{% extends 'base.html' %}
{% block content %}
<div class="container my-3" style="max-width:700px;">
<div class="text-center my-3">
<h2>日報を編集</h2>
</div>
<form method="POST"> {% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary form-control" type="submit">編集</button>
</form>
</div>
{% endblock %}
urls.py
from django.urls import path
from .views import NippoUpdateView
urlpatterns = [
#...,
path("update/<slug:slug>/", NippoCreateView.as_view(), name="nippo-update"),
]
まとめ

当記事の内容をまとめます。
ModelFormとは、既存のモデルと連携されたフォームを作成するためのフォームクラスです。
ModelFormクラスの書き方では下記の3つをおさえましょう。
- Metaクラスの定義
- モデルクラスを指定すること
- フィールドを指定すること
さて、当記事のCreateView、UpdateViewは、当ブログを通じて作成中の日報アプリの一部です。
その点でみると、現状2点の修正すべき点が出てきました。
①ラベル元が英語表記になっている②フィールドが自動でinputになってしまっている点です。

Formクラスと同じようにフィールド内でwidgetによる書き換えも可能ですが、今後のことも考えて別の方法をご紹介します。
次回の記事では、models.pyでラベルの書き換え、日本語表記にする方法、を解説していきます。
当記事をご覧の方の中にも「そろそろウェブでアプリを公開してみたいなぁ」「どうやって公開するの?」という方もいらっしゃるのではないでしょうか?
下記の通り、別記事ではDjangoアプリの公開方法や公開までの準備についての解説をしていますのでご覧ください!
「Webアプリを公開したい!」という方へ
当ブログでは、日報アプリ開発を通じて、Webアプリを一から開発し公開するまでを初学者の方でもわかるようにと記事を連載しています
「Djangoでのアプリ開発を学びたい!」
「Djangoで開発したアプリをWebで公開するにはどうするの?」
という方は必見です!
