サイトアイコン ITC Media

【完全版】Django form(フォーム)の表示・保存・編集

フォームクラスを使ってフォームを表示しよう!

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

✔当記事はこんな疑問をお持ちの方へ向けて書かれています

「Djangoを使ってフォームを表示させたい!どうするの?」

「フォームからデータを送信・保存するには?」

「既存のデータを編集するにはどうするの?フォームへ初期値を設定したい!」

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

Djangoでフォームを扱う方法は3つあります。

  1. HTMLに直接記述する
  2. Formクラスを作成しビューと紐付ける方法
  3. ModelFormクラスを作成しビュート紐付ける方法

当記事では、「Formクラス」による方法でご紹介します。

ModelFormクラスで記述する方法は、当記事の内容を応用すればスムーズです。

一度当記事をお読みになってから、下記よりModelFormでの方法へお進みください↓

当記事ではこんなフォームを作っていきます。

フォームをブラウザに表示する方法

フォームクラスを使ったフォームの表示方法は下記の流れとなります。

  1. forms.Formを継承したFormクラスを作成する
  2. ビュー関数で、作成したフォームクラスをHTMLテンプレートへ渡す
  3. HTMLテンプレートでフォームを受け取り表示する
  4. ビュー関数とURLを紐付ける

Formクラスを作成する

フォームクラスはどこに作っても構いませんが、「forms.py」という新たなファイルに記述することがおすすめです。

なぜなら、Webアプリが複雑になってきても、どこに記述したかがわかりやすいから。

forms.py

✔︎form.pyの作成

プロジェクトフォルダ「src」 > appフォルダ「nippo」 > forms.py

src #プロジェクトフォルダ
├── nippo #appフォルダ
.
.
│   ├── forms.py #こちらを作成しました。
.
.
│   ├── urls.py
│   └── views.py
├── #その他フォルダ

✔︎forms.Formの作成

from django import forms

class NippoFormClass(forms.Form):
    title = forms.CharField()
    content = forms.CharField()

コードの解説

djangoライブラリからformsをインポートします。

from django import forms

forms.Formを継承したクラスを作成します。

class フォームクラス名(forms.Form):

フィールドを作成します。

フィールド名 = forms.フィールド種類()

フォームクラスをHTMLテンプレート渡す

ビュー関数内のコンテキストで、テンプレートへフォームを渡します。

views.py

from .forms import  NippoFormClass

def nippoCreateView(request):
    template_name="nippo/nippo-form.html"
    form = NippoFormClass()
  ctx = {}
    ctx["form"] = form
    return render(request, template_name, ctx)

コード解説

作成したフォームクラスをインポートします。

from .forms import  NippoFormClass

関数内でフォームのインスタンスを作成します。

form = NippoFormClass()

フォームをテンプレートへ渡します。

ctx = {}
ctx["form"] = form
return render(request, template_name, ctx)

HTMLテンプレートでフォームを受け取り表示する

ビュー関数から渡されたフォームを受け取り、表示します。

nippo-form.html

{% extends "base.html" %}

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

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

コード解説

formタグで囲い、POSTメソッドを指定します。

<form method="POST"></form>

formタグ内で{% csrf_token %}タグを記述します。

<form method="POST">{% csrf_token %}</form>

ビュー関数から渡された変数「form」をas_pメソッドで展開します。

<form method="POST">{% csrf_token %}
    {{ form.as_p }}
</form>

submit用のボタンを設置します。

<form method="POST"
    {{ form.as_p }}
    <button type="submit">送信</button>
</form>

ビュー関数とURLを紐付ける

ビュー関数とURLを紐付けます。

nippo > urls.py

from django.urls import path
from .views import nippoCreateView

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

※当チュートリアルで既に設定されている方は、特に何もしなくて良いです。

アクセスして確かめる

http://localhost:8000/nippo/create

無事表示されました。

ただこのままではデータの保存ができません。

フォームからデータを送信・保存する方法

submitボタンより送信された値は、request.POSTにより受け取ることができます。

詳しくご覧になりたい方はこちらの記事をどうぞ↓

ただし、フォームクラスを使用した場合は、少し異なります。

それぞれ順をおって見ていきます。

views.py:ビュー関数の記述方法

受け取った値を保存するまでのコードは下記の通りです。

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

コードの解説

フォームクラスには、空、もしくは送信データのどちらかが入るため、「or」を使い一行で入力を済ませます。

form = NippoFormClass(request.POST or None)

「if request.POST == ‘POST’」などの表記も使えますがこちらの方が短く簡単です。

フォームの送信時にエラーが無いかをチェックします。

if form.is_valid():

フォームにエラーがある場合は、if文以下は実行されません。

cleaned_data[フィールド名]で値をそれぞれ変数へ入れていきます。

title = form.cleaned_data["title"]
content = form.cleaned_data["content"]

モデルクラスのインスタンスを作り、保存します。

obj = NippoModel(title=title, content=content)
obj.save()

フォームへの保存は完了です。

編集したい時はどうするのでしょうか?

フォームへ初期値を設定する方法を解説していきます。

編集フォームの作成|初期値の設定方法

フォームへ初期値を渡すには、{フィールド名: 値}の辞書型を引数で渡すことで設定可能です。

アップデートビュー関数は下記の通りとなります。

def nippoUpdateFormView(request, pk):
    template_name = "nippo/nippo-form.html"
    obj = NippoModel.objects.get(pk=pk)
    initial_values = {"title": obj.title, "content":obj.content}
    form = NippoFormClass(request.POST or initial_values)
    ctx = {"form": form}
    if form.is_valid():
        title = form.cleaned_data["title"]
        content = form.cleaned_data["content"]
        obj.title = title
        obj.content = content
        obj.save()
    return render(request, template_name, ctx)

ポイントはデータベースからの値を渡している箇所です。

obj = NippoModel.objects.get(pk=pk)   
initial_values = {"title": obj.title, "content":obj.content}
form = NippoFormClass(request.POST or initial_values)

アップデートビューについては、チュートリアル3-4にて、詳しく解説していきます。

フォームwidgetsの設定|textareaへの変更、placeholder

現状のフォームを少し変更する必要があります。

なぜなら、以下の点があまりよくないからです。

現状

変更後

これらをひとつずつ変更していきます。

フォームウィジットで、フォームをテキストエリアに変更する

テキストエリアへ変更するには、フォームウィジットを使います。

フォームウィジットとは、フォームフィールド内の引数で設定します。

forms.フォームフィールド(widget=forms.フォームフィールド)

✔変更前

content = forms.CharField()

✔変更後

content = forms.CharField(widget=forms.Textarea())

以下のとおりとなりました。

placeholderの設定

placeholderの設定もウィジット内でおこないます。

forms.フォームフィールド(widget=forms.フォームフィールド(attrs={‘placeholder’:’プレースホルダ’}))

inputとtextareaそれぞれで、以下のとおりとします。

title = forms.CharField(widget=forms.TextInput(attrs={'placeholder':'タイトル...'}))
content = forms.CharField(widget=forms.Textarea(attrs={'placeholder':'内容...'}))

プレースホルダがつきました。

label表記の設定

labelの表記を任意の値にします。

labelは、ウィジット内ではなく、ウィジットと並列の引数で設定します。

form.フォームフィールド(label=ラベル名)

当アプリでは以下のとおりとします。

title = forms.CharField(label="タイトル", widget=forms.TextInput(attrs={'placeholder':'タイトル...'}))
content = forms.CharField(widget=forms.Textarea(attrs={'placeholder':'内容...'}), label="内容")

現状はこちらで完了とします。

まとめ

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

フォームを表示する方法として、Formクラスを使った方法を解説しました。

表示するまでのステップは下記の通りです。

  1. forms.Formを継承したFormクラスを作成する
  2. ビュー関数で、作成したフォームクラスをHTMLテンプレートへ渡す
  3. HTMLでフォームを受け取り表示する
  4. ビュー関数とURLを紐付ける

フォームからデータを受け取る際には、下記のように記述すると便利です。

form = フォームクラス(request.POST or None)

フォーム変数から値を受け取るために、①is_validメソッドでエラーチェック②cleaned_data属性で値を取得する方法を解説しました。

自身でも色々と試しながら当記事の内容をしっかりと身につけましょう。

次回は、Webアプリ機能「CRUD」の中の「U」アップデート機能を持ったページについて解説します

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