サイトアイコン ITC Media

【Django】ModelFormとは?書き方から具体例まで解説

(最終更新月:2022年3月)

✔このような方へ向けて書かれた記事となります

「ModelFormって何?Formクラスと何が違うの?」

「ModelFormの書き方、使い方が知りたい!」

「ModelFormを使った具体例が見てみたい。」

✔当記事を通じてお伝えすること

✔独学におすすめ

ModelFormとは?Formクラスとの違いは?

ModelFormについての基本事項を見ていきます。

書き方を学ぶ前に、必ず目を通しておく必要があるものです。

ModelFormとは?

ModelFormとは、既存のモデルと連携されたフォームを作成するためのフォームクラスです。

models.pyで指定されたフィールドが、フォームフィールドとして自動で表示されるようになります。

Formクラス同様に、formsモジュール内に存在します。

from django.forms import ModelForm

Formクラスとの違い

ModelFormとFormクラスの違いを見ていきましょう。

違いを理解することで、場面によって使い分けられるようになるからです。

ModelFormクラス|Formクラスとの違い

Formクラスとの違いは、モデルクラスとの連携。

連携することにより、以下のことが不要になります。

入力したデータをデータベースに保存したいなら、ModelFormが便利です。

Formクラスの構成

具体的にFormクラスの記述を見てみると以下のとおり。

from django import forms

class TestForm(forms.Form):
    field1 = forms.CharField(max_length=255)
    field2 = forms.IntegerField()
    fields3 = ....
    ....

特に既存のモデルとは関係がなく、必要なフィールドを全て記述していきます。

ModelFormクラスの構成

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の基本 〜 書き方編

ModelFormの書き方をご紹介します。

以下の2つでの記述を覚えておく必要があるのです。

forms.py:ModelFormの書き方

構成としては下記の通りとなります。

from django import forms
from .models import モデル名

class フォームクラス名(forms.ModelForm):
    class Meta:
        model = モデル名
        fileds = "__all__" #表示するフィールドを指定します。

ポイントは3つです。

  1. 継承したクラス内でMetaクラスを定義
  2. model」変数で保存・編集するモデルクラスを指定
  3. fields」変数で使用するフィールドを指定

3.「fields」の記述方法は以下の3つです。

#フィールド全て
fields = "__all__"

#フィールドの一部
fields = ["フィールド1", "フィールド2"]

#一部のフィールドを除く
exclude = "除きたいフィールド"

views.py:クラスベースビュー内での書き方

ビューの書き方としては基本はフォームクラスと同様です。

ただし、form_validメソッドは割愛することも可能です。

from django.views.generic.edit import CreateView
from .forms import フォームクラス名

class ビュークラス名(CreateView):
    template_name = テンプレートパス
    form_class = フォームクラス名
    success_url = URLパス

「Formクラスの書き方を知りたい!」という方はこちらをご覧ください。

具体例:日報アプリを使ってModelFormの使い方を解説

日報アプリを使って、ModelFormの使い方を見ていきましょう。

以下の2つのビュークラスを作成します。

日報アプリのモデルクラスは以下のとおりとなっています。

class NippoModel(models.Model):
    title = models.CharField(max_length=100)
    content = models.CharField(max_length=1000)
    timestamp = models.DateTimeField(auto_now_add=True)

CreateViewの作成

以下の4つのコードを見ていきましょう。

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 NippoCreateModelFormView(CreateView):
    template_name = "nippo/nippo-form.html"
    form_class = NippoModelForm
    success_url = reverse_lazy("nippo-list")

ポイントは下記の通りです。

htmlテンプレート:nippo-form.html

{% extends "base.html" %}
{% block title %}
    {% if object %}
        日報「{{ object.title }}」の編集
    {% else %}
        日報の新規作成
    {% endif %}
{% endblock %}
{% block content %}
<div class="container my-3" style="max-width:700px;">
    <form method="POST"> {% csrf_token %}
    {{ form.as_p }}
    <button class="form-control btn btn-primary" type="submit">登録</button>
    </form>
</div>
{% endblock %}

urls.py

from django.urls import path
from .views import NippoCreateModelFormView

urlpatterns = [
    path("create/", NippoCreateModelFormView.as_view(), name="nippo-create"),
]

CreateViewについて詳しく解説を見たい方はこちらをご覧ください。

UpdateViewの作成

同じModelFormを使用しますので、forms.pyとhtmlテンプレートのコードは同じです。

以下の2つを見ていきましょう。

views.py

class NippoUpdateModelFormView(UpdateView):
    template_name = "nippo/nippo-form.html"
    model = NippoModel
    form_class = NippoModelForm
    success_url = reverse_lazy("nippo-list")

urls.py

from django.urls import path
from .views import NippoUpdateModelFormView

urlpatterns = [
    #...,
    path("update/<int:pk>/", NippoUpdateModelFormView.as_view(), name="nippo-update"),
]

まとめ

当記事の内容をまとめます。

ModelFormとは、既存のモデルと連携されたフォームを作成するためのフォームクラスです。

ModelFormクラスの書き方では下記の3つをおさえましょう。

  1. Metaクラスの定義
  2. モデルクラスを指定すること
  3. フィールドを指定すること

さて、当記事のCreateView、UpdateViewは、当ブログを通じて作成中の日報アプリの一部です。

その点でみると、現状2点の修正すべき点が出てきました。

①ラベル元が英語表記になっている②フィールドが自動でinputになってしまっている点です。

Formクラスと同じようにフィールド内でwidgetによる書き換えも可能ですが、今後のことも考えて別の方法をご紹介します。

次回の記事では、models.pyでラベルの書き換え、日本語表記にする方法、を解説していきます。

モバイルバージョンを終了