【Django】FormViewとは?書き方・実例付で徹底解説

※本サイトにはプロモーション・広告が含まれています。

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

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

「Django FormViewって何?何が便利なの?」

「Django FormViewの作り方が知りたい!」

「Django FormViewの使い方、保存方法はどうやるの?」

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

  • Django FormViewとは?
  • Django FormViewの作り方をステップ・バイ・ステップで解説
  • FormViewの使い方|保存方法を解説

✔YouTube解説動画

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

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

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

✔独学におすすめ

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

Django FormViewとは?

DjangoのFormViewとは、オリジナルのフォームクラスと容易に連携ができる、ォームを扱うためのクラスベースビューになります。

他のフォームを扱うクラスベースビュー「CreateView」「UpdateView」などとは違い、モデルクラスとの連携はなく、自由度の高い点がメリットと言えます。

下記より、FormViewを使って、①フォームを表示する②入力したデータを保存する、方法を解説していきます。

最終的には、別記事で作成したファンクションビュー「nippoCreateView」と同じ機能をFormViewを使って実現していきます。

def nippoCreateView(request):
    template_name = "nippo/nippo-create.html"
    form = NippoForm(request.POST or None)
    ctx = {"form": form}
    if request.POST:
        if form.is_valid():
            title = form.cleaned_data["title"]
            content = form.cleaned_data["content"]
            obj = NippoModel(title=title, content=content)
            obj.save()
            return redirect("nippo-list")
    return render(request, template_name, ctx)

Django FormViewの作り方をステップ・バイ・ステップで解説

まずはブラウザへ表示するまでを記述していきます。

nippo > forms.py

from django import forms

class NippoFormClass(forms.Form):
    title = forms.CharField(max_length=100, label="タイトル")
    content = forms.CharField(widget=forms.Textarea(), max_length=1000, label="内容")

    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」クラスをフォームに適用するための記述になります。

詳しくはこちらでご説明しています。

nippo > views.py

from django.views.generic import FormView
#...ほかのインポートは省略

class NippoCreateFormView(FormView):
    template_name = "nippo/nippo-form.html"
    form_class = NippoFormClass
    success_url = "/nippo/"

フォームを表示するためには、下記の4点を押さえておきましょう。

  1. FormViewのインポートし、継承したクラスを作成する
  2. template_nameでHTMLテンプレートを指定する
  3. form_classで使用するFormクラスを指定する
  4. success_urlでフォーム送信後のリダイレクト先を指定する

nippo > templates > nippo-formclass.html

{% extends "base.html" %}

{% block title %}日報を作成しよう{% endblock %}

{% block content %}
    <form method="POST">{% csrf_token %}
        {{ form.as_p }}
        <button type="submit">送信</button>
    </form>
{% endblock %}

nippo > urls.py

from django.urls import path
from .views import NippoCreateFormView

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

これで表示まで完了です。

ただ値を入力しても何も起こりませんので、保存するためのメソッドを追加していきます。

FormViewの使い方|保存方法を解説

保存方法の記述はviews.py内で行い、FormViewで用意されているメソッドを書き換えていきます。

nippo > views.py

class NippoCreateFormView(FormView):
    template_name = "nippo/nippo-form.html"
    form_class = NippoForm
    success_url = "/nippo/"

    def form_valid(self, form):
        data = form.cleaned_data
        obj = NippoModel(**data)
        obj.save()
        return super().form_valid(form)

データの受取・保存の役割を担う関数は「form_valid」で、今回の記述は下記の通りです。

def form_valid(self, form):
    data = form.cleaned_data
    obj = NippoModel(**data)
    obj.save()
    return super().form_valid(form)

コードの解説

始まりと終わりは下記の通りです。

間に必要なコードを記述していきます。

def form_valid(self, form): 
  #処理を記述するのはここです
  return super().form_valid(form) 

下記の点を押さえましょう。

  • form_validメソッドは、フォームがエラーなく送信された際に実行される関数
  • 引数として、「self」以外に「form」を受け取る
  • return super().form_valid(form)」で終わること

cleaned_data属性を使用し、入力したデータを辞書型で取り出せます。

data = form.cleaned_data

オブジェクト「obj」を作り、保存します。

obj = NippoModel(**data)
obj.save()

モデルクラス名(**辞書型オブジェクト)

とすることで、辞書型のキーがモデルクラスのフィールド名と一致している場合、そのまま値が代入されオブジェクトが作れます。

補足として2点頭に入れておくことをお勧めします。

  1. 変数「form_class」は、get_form_classメソッドと置き換えることが可能
  2. 変数「success_url」は、get_success_urlメソッドと置き換えることが可能

これらのメソッドは、動的にフォームクラスやリダイレクト先を変更したい場合など使用すると便利です。

まとめ

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

FormViewとは、オリジナルのフォームクラスと容易に連携ができる、フォームを扱うためのクラスベースビューになります。

FormViewを使ってフォームを表示するためには、下記の4ステップを覚えておく必要があります。

  1. FormViewのインポートし、継承したクラスを作成する
  2. template_nameでHTMLテンプレートを指定する
  3. form_classで使用するFormクラスを指定する
  4. success_urlでフォーム送信後のリダイレクト先を指定する

また、データ保存の際は、form_validメソッド内でデータの受取、保存を行います

合わせて記述方法を覚えておきましょう。

さて、当記事でご紹介したコードの中で一点変更を実は変更すべき箇所があります。

それは、success_url変数で代入したURLです。

現状では、URLの相対パスを直接入力しています。

success_url = "/nippo/"

このやり方は、今後URLに変更を加えた場合、いちいち全てのコードを見直して変更する必要があり、面倒です。

Djangoには、ページ名からURLを返す便利なメソッドが用意されていますので、次回は「reverse_lazy」メソッドについてカンタンに解説しコードをよりブラッシュアップしていきましょう!

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