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

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

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

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

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

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

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

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

  • フォームクラスの作り方
  • フォームクラスでデータを保存する方法
  • 編集フォームの作成|初期値の設定方法
  • フォームウィジットの設定方法

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

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

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

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

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

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

✔YouTube解説動画

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

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

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

筆者プロフィール

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  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

無事表示されました。

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

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

python

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

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

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

  • views.py:ビュー関数の記述方法
  • コードの解説

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

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

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

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

  • 日報の内容がテキストエリアでない
  • placeholderがない
  • labelが英語表記

現状

変更後

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

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

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

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

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」アップデート機能を持ったページについて解説します

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

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