【Django】フォームForm:データベースへの新規登録・更新機能を組み込む(instance変数)

2021.12.07 /

【Django】フォームForm:データベースへの新規登録・更新機能を組み込む(instance変数)

本記事ではDjangoフォームを使ったデータベースの新規登録更新機能の組み込み方法を解説していきます。

データベースに情報を新規登録または登録した情報の編集機能を追加したい場合、Djangoのフォームを利用することで簡単に実装できます。本記事ではinstance変数を利用します。

サンプルプログラムも載せていますので、実際に書いて動かしてみて使い方を覚えてください。

Djangoでのフォームの作成については以下記事をご参照ください。

フォームクラスを利用した更新

フォームクラスを利用することでデータベースの情報更新ページの作成が非常に楽になります。

フォームクラスについては以下記事をご参照ください。

ここではmodels.pyとforms.pyは次のように設定されているとします。

# models.py
from django.db import models

class Member(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    address = models.CharField(max_length=255)
    age = models.PositiveIntegerField()
    mail = models.EmailField()
# forms.py
from django import forms
from .models import Member

class MemberForm(forms.ModelForm):
    class Meta:
        model = Member
        fields = ('first_name', 'last_name', 'address', 'age', 'mail')

モデルMemberはサイト会員情報を保持するモデルです。

views.pyではこのフォームクラスMemberFormを利用して、フォーム情報をテンプレートに送信します。

新規登録

新規会員登録ページを表示する場合、以下のようにフォームクラスをインスタンス化してテンプレートに渡します。

form = MemberForm()
return render(request, "member _new.html", {'form': form})

上記ように、単にフォーム情報を渡すだけの場合は引数には何も指定しません。

新規会員登録ページから送られてきた新規会員情報をデータベースに登録する場合、以下のようにフォームクラスの引数にはrequest.POSTのみを渡します。

form = MemberForm(request.POST)
    if form.is_valid():
        form.save()

フォームクラスにrequest.POSTのみを渡すことでDjangoはsave()時に新規登録としてデータベースに登録します。

データ更新

会員情報更新ページを表示する場合、以下のようにinstance変数をフォームクラスの引数に使用します。現在の情報をフォームに組み込んでインスタンス化しテンプレートに渡しています。

member = get_object_or_404(Member, pk=member_id)
form = MemberForm(instance=member)
return render(request, 'member_edit.html', {'form': form})

会員情報更新ページから送られた更新情報をデータベースに反映させる場合、以下のように引数にrequest.POSTとinstance変数を利用します。

member = get_object_or_404(Member, pk=member_id)
if request.method == "POST":
    form = MemberForm(request.POST, instance=member)
    if form.is_valid():
        form.save()

フォームクラスにrequest.POSTとinstance変数を渡すことでsave()時の動作が更新処理になります。

フォームクラスの引数 説明
引数なし フォーム情報のみ
引数にinstance変数のみ 現在の情報をフォームに反映
引数にrequest.POST save()時の挙動が新規登録
引数にrequest.POSTとinstance変数 save()時の挙動が更新登録

更新処理の画面推移

実際にサンプルアプリケーションのコードを見ていただき、データベースへの新規登録からデータ更新の方法を確認していきましょう。

ここで作成するWebアプリケーションは次の流れで画面が遷移していきます。

  1. サイトにアクセスすると会員一覧ページが表示
  2. 会員一覧ページ
  3. 会員登録ボタンを押すと会員登録ページへ移動
  4. 会員登録ページ
  5. 会員登録をすると会員詳細ページへ移動
  6. 会員詳細ページ
  7. 会員情報変更ボタンを押すと会員情報変更ページへ移動
  8. 会員情報変更ページ
  9. 会員情報変更が完了すると会員詳細ページへ移動

次項より各ページのコードをご紹介していきます。

このWebアプリケーションはアプリケーションfiveで動いており、forms.pyとmodels.pyは既述したものを利用しています。

会員一覧ページ

会員一覧ページでは登録されている会員がすべて表示されます。

会員一覧ページ

views.pyでは次のように書き込まれています。

def index(request):
    members = Member.objects.all()
    context = {'members': members,}
    return render(request, 'five/index.html', context)

htmlファイルは次のように書き込まれています。

<h2>会員一覧</h2>
<table>
    <thead>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Age</th>
        </tr>
    </thead>
    <tbody>
        {% for member in members %}
        <tr>
            <th></th>
            <th></th>
            <th></th>
        </tr>
        {% endfor %}
    </tbody>
</table>
<a class="btn btn-primary" href="{% url 'member_new' %}">会員登録</a>

会員登録ボタンを押すことで次のページ(会員登録ページ)へ遷移します。

会員登録ページ

会員登録ページでは会員情報を入力するフォームが表示され、新規で会員を登録できるページです。

会員登録ページ

views.pyでは次のように書き込まれています。

def member_new(request):
    if request.method == "POST":
        form = MemberForm(request.POST)
        if form.is_valid():
            member = form.save()
            return redirect(member_detail, member_id=member.pk)
    else:
        form = MemberForm()
    return render(request, "five/member_new.html", {'form': form})

htmlファイルは次のように書き込まれています。

<h2>新規会員登録</h2>
<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" name="button">保存</button>
</form>

新規会員の登録が完了すると、その会員の詳細ページが開きます。

会員詳細ページ

会員詳細ページでは対象の会員の情報が表示されます。

会員詳細ページ

urls.pyの次のコードでルーティングされます。

path("<int:member_id>/", views.member_detail, name="member_detail"),

views.pyでは次のように書き込まれています。

def member_detail(request, member_id):
    member = get_object_or_404(Member, pk=member_id)
    return render(request, 'five/member_detail.html', {'member': member})

htmlファイルは次のように書き込まれています。

<h2>会員詳細</h2>
<p>First Name:{{ member.first_name }}</p>
<p>Last Name:{{ member.last_name }}</p>
<p>Age:{{ member.age }}</p>
<p>Address:{{ member.address }}</p>
<p>Mail:{{ member.mail }}</p>
<a href="{% url 'member_edit' member.id %}">会員情報変更</a>

会員情報変更ボタンを押すことで会員情報変更ページに推移します。

会員情報変更ページ

会員情報変更ページではフォーム内に登録されている情報が記入されており、必要な個所を変更できるようになっています。

会員情報変更ページ

urls.pyの次のコードでルーティングされます。

path("<int:member_id>/edit/", views.member_edit, name="member_edit"),

views.pyでは次のように書き込まれています。

def member_edit(request, member_id):
    member = get_object_or_404(Member, pk=member_id)
    if request.method == "POST":
        form = MemberForm(request.POST, instance=member)
        if form.is_valid():
            form.save()
            return redirect('member_detail', member_id=member_id)
    else:
        form = MemberForm(instance=member)
    return render(request, 'five/member_edit.html', {'form': form})

htmlファイルは次のように書き込まれています。

<h2>会員情報の変更</h2>
<form action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" name="button">保存</button>
</form>

まとめ

本記事「【Django】フォームForm:データベースへの新規登録・更新を組み込む(instance変数)」はいかがでしたか。

Djangoはフォームクラスの引数によって新規登録か更新登録なのかを判断します。これを知っているだけで、データベースへの新規登録や更新機能を簡単に実装できるようになります。

ぜひDjangoによるWebアプリケーション開発に活かしてください。