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

Django

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

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

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

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

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

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

  • ModelFormとは?Formクラスと使い分けるには?
  • ModelFormの基本〜書き方編
  • ModelFormの具体例をお見せします

【著者プロフィール】

profile_icon
【Python歴】11年 x 【Django歴】10年
HP作成、社内システムの構築、コンサルティング

当ブログを通じて、Webアプリの書き方やアプリの公開方法までを解説しています。

☆日報アプリ「D-Repo」(デモ版)→こちら

※Djangoをベースに作成したアプリです。

☆便利ツールアプリ「Tool Station」→こちら

※Django REST frameworkとReactで作成しているアプリです。

✔YouTube解説動画

当記事の内容は動画を見ながら進めると、約15分程度で完了します。

動画ならではの情報も解説しているので、記事と一緒にご覧ください。

動画の概要欄には、単元ごとのコードを紹介しているgithubページも載せています。

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

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

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

  • ModelFormとは
  • Formクラスとの違い
  • ModelFormのメリット・デメリット

ModelFormとは?

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

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

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

from django.forms import ModelForm

Formクラスとの違い

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

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

  • Formクラスとの違い
  • Formクラスの構成
  • ModelFormクラスの構成

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クラスのメリット

  • モデルクラスのフィールドを簡単に引き継げる
  • Formクラス同様、好きなフォームフィールドも追加できる
  • 保存や編集の際も連動して動くため、保存のためのメソッドについては記述不要

ModelFormクラスのデメリット

  • 紐付けるモデルが必要
  • 書き方のルールを覚える必要がある

対象のモデルが決まっていて、データを保存、編集したい場合はModelFormが適しているといえます。

ModelFormの基本 〜 書き方編

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

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

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

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つのビュークラスを作成します。

  • CreateView
  • UpdateView

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

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
  • views.py
  • htmlテンプレート
  • urls.py

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")

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

  • CreateViewのインポート
  • 「template_name」「form_class」「success_url」変数へ値を格納
  • form_valid関数は不要

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
  • urls.py

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でラベルの書き換え、日本語表記にする方法、を解説していきます。

✔ウェブアプリを公開したい方へのおすすめ記事

【保存版】Apache WebサーバーでDjangoアプリを公開
Djangoが公開できる月500円~のレンタルサーバー
【初心者向け】ムームードメインで独自ドメインを取得する3ステップ
【実体験】マイIPの使い方を解説|固定IPアドレスを取得・設定する

✔当ブログは以下のような方に向けて書かれています

「Djangoでのアプリ開発を学びたい!」

「Djangoで開発したアプリをWebで公開するにはどうするの?」

✔当ブログ掲載の記事

  • Djangoで作る日報アプリ開発
  • WebアプリをWeb上に公開する方法
  • Webアプリ開発に必要なそのほかの情報
【Django】チュートリアル|日報アプリの開発から公開まで
Djangoのチュートリアルをお探しですか?具体的に「手を動かして作ってみたい!」という方へ向けて、誰でもできる簡易的な日報アプリの開発を通じて、Djangoの様々な機能に触れていくシリーズとなっています。PythonでWebアプリを作りたい方、必見の記事となります!

ITCブログにご協力いただける方は、以下もご検討いただけると嬉しいです。

ITCへ投げ銭をする

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