(最終更新月:2022年3月)
✔このような方へ向けて書かれた記事となります
「Django FormViewって何?何が便利なの?」
「Django FormViewの作り方が知りたい!」
「Django FormViewの使い方、保存方法はどうやるの?」
✔当記事を通じてお伝えすること
- Django FormViewとは?
- Django FormViewの作り方をステップ・バイ・ステップで解説
- FormViewの使い方|保存方法を解説
✔YouTube解説動画
当記事の内容は動画を見ながら進めると、約15分程度で完了します。
動画ならではの情報も解説しているので、記事と一緒にご覧ください。
動画の概要欄には、単元ごとのコードを紹介しているgithubページも載せています。
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点を押さえておきましょう。
- FormViewのインポートし、継承したクラスを作成する
- template_nameでHTMLテンプレートを指定する
- form_classで使用するFormクラスを指定する
- 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点頭に入れておくことをお勧めします。
- 変数「form_class」は、get_form_classメソッドと置き換えることが可能
- 変数「success_url」は、get_success_urlメソッドと置き換えることが可能
これらのメソッドは、動的にフォームクラスやリダイレクト先を変更したい場合など使用すると便利です。
まとめ
当記事の内容をまとめます。
FormViewとは、オリジナルのフォームクラスと容易に連携ができる、フォームを扱うためのクラスベースビューになります。
FormViewを使ってフォームを表示するためには、下記の4ステップを覚えておく必要があります。
- FormViewのインポートし、継承したクラスを作成する
- template_nameでHTMLテンプレートを指定する
- form_classで使用するFormクラスを指定する
- success_urlでフォーム送信後のリダイレクト先を指定する
また、データ保存の際は、form_validメソッド内でデータの受取、保存を行います。
合わせて記述方法を覚えておきましょう。
さて、当記事でご紹介したコードの中で一点変更を実は変更すべき箇所があります。
それは、success_url変数で代入したURLです。
現状では、URLの相対パスを直接入力しています。
success_url = "/nippo/"
このやり方は、今後URLに変更を加えた場合、いちいち全てのコードを見直して変更する必要があり、面倒です。
Djangoには、ページ名からURLを返す便利なメソッドが用意されていますので、次回は「reverse_lazy」メソッドについてカンタンに解説しコードをよりブラッシュアップしていきましょう!