(最終更新月:2022年3月)
✔このような方へ向けて書かれた記事となります
「ModelFormって何?Formクラスと何が違うの?」
「ModelFormの書き方、使い方が知りたい!」
「ModelFormを使った具体例が見てみたい。」
✔当記事を通じてお伝えすること
- ModelFormとは?Formクラスと使い分けるには?
- ModelFormの基本〜書き方編
- ModelFormの具体例をお見せします
✔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つです。
- 継承したクラス内でMetaクラスを定義
- 「model」変数で保存・編集するモデルクラスを指定
- 「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つをおさえましょう。
- Metaクラスの定義
- モデルクラスを指定すること
- フィールドを指定すること
さて、当記事のCreateView、UpdateViewは、当ブログを通じて作成中の日報アプリの一部です。
その点でみると、現状2点の修正すべき点が出てきました。
①ラベル元が英語表記になっている②フィールドが自動でinputになってしまっている点です。
Formクラスと同じようにフィールド内でwidgetによる書き換えも可能ですが、今後のことも考えて別の方法をご紹介します。
次回の記事では、models.pyでラベルの書き換え、日本語表記にする方法、を解説していきます。
✔ウェブアプリを公開したい方へのおすすめ記事