こんにちは。sinyです。
この記事では、DjangoのCreateViewを使ったデータ登録処理の完了時に、処理結果として登録したデータレコードを表示する方法を紹介します。
<参考デモ動画>
実装手順
models.py
以下のようなモデルを前提に説明していきます。
from django.db import models from datetime import datetime from django.utils import timezone class Category(models.Model): class Meta: #カテゴリ verbose_name ="カテゴリ" verbose_name_plural ="カテゴリ" #カラム名の定義 category_name = models.CharField(max_length=255,unique=True) def __str__(self): return self.category_name class Kakeibo(models.Model): class Meta: verbose_name ="家計簿" verbose_name_plural ="家計簿" #カラムの定義 date = models.DateField("日付",default=datetime.now) category = models.ForeignKey(Category, on_delete = models.PROTECT, verbose_name="カテゴリ") money = models.IntegerField("金額", help_text="単位は日本円") memo = models.CharField(verbose_name="メモ", max_length=500) def __str__(self): return self.memo
まず最初に、Kakeiboテーブルクラスに get_absolute_urlを追加して、Djangoのreverse()関数を通したURLを返すようにします。
def get_absolute_url(self): return reverse("kakeibo:create_done", kwargs={ 'pk': self.pk, 'category': self.category, 'money': self.money, 'memo': self.memo, })
reverseメソッドの引数にリダイレクト先のURLパターン「kakeibo:create_done」を指定し、「kwargs=」にリダイレクトしたい新規登録したレコードのpkキー、カテゴリ名(category)、金額(money)、メモ(memo)の値を指定しておきます。
イメージとしては、新規データ登録が完了したら、そのレコードの内容をURLパターン「kakeibo:create_done」に渡してあげるといった感じです。
urls.py
URLパターンの設定は以下のようにします。
from django.urls import path from . import views app_name = 'kakeibo' urlpatterns = [ path('kakeibo_list/', views.KakeiboListView.as_view(), name='kakeibo_list'), path('kakeibo_create/', views.KakeiboCreateView.as_view(), name='kakeibo_create'), path('create_done/<int:pk>/<category>/<int:money>/<memo>/', views.create_done, name='create_done'),#設定箇所 ]
データ登録が完了した際にCALLされるURLパターン「create_done」のURLパターンを'create_done/<int:pk>/<category>/<int:money>/<memo>/'のように指定します。
path('create_done/<int:pk>/<category>/<int:money>/<memo>/', views.create_done, name='create_done'),#設定箇所
forms.py
ModelFormを使って登録画面用のフォームを定義します。
普通のフォーム定義なので特に難しい部分はないと思います。
from django import forms from .models import Kakeibo class KakeiboForm(forms.ModelForm): """ 新規データ登録画面用のフォーム定義 """ class Meta: model = Kakeibo fields =['date', 'category', 'money', 'memo']
views.py
データ登録用にDjango汎用ビューのCreateViewを承継して登録用のクラスを定義します。
利用するモデルにKakeibo、利用するフォームクラス名には先ほどforms.pyで定義したKakeiboFormを指定します。
from django.shortcuts import render from . forms import KakeiboForm from django.views.generic import CreateView from .models import Category, Kakeibo from django.db import models class KakeiboCreateView(CreateView): #利用するモデルを指定 model = Kakeibo #利用するフォームクラス名を指定 form_class = KakeiboForm
ここまでは普通のCreateViewの定義です。
続いて以下のcreate_done関数を追加します。
これは、データ登録処理が完了した際に呼び出される関数で、最終的にデータ登録完了画面(create_done.html)が呼び出されます。
def create_done(request, **kwargs): contents = {} for key, val in kwargs.items(): contents[key] = val return render(request, 'kakeibo/create_done.html',{ 'contents': contents, })
create_done関数の第1引数でrequestを受け取り、第2引数は「**kwargs」と指定することでmodels.pyのget_absolute_urlで指定した辞書データkwargsを受け取ります。
以下の部分で、**kwargsに格納されている新規登録されたレコードの値を1つずつ取り出して辞書型変数contentsに格納していきます。
contents = {} for key, val in kwargs.items(): contents[key] = val
最後に、以下の通りreturn renderにcontentsを指定することでテンプレート側に登録されたレコード情報を渡してあげます。
return render(request, 'kakeibo/create_done.html',{ 'contents': contents, })
テンプレート
最後に、テンプレート側で辞書型データcontentsを受け取り、値を表示してあげます。
{% for key, value in contents.items%} <th>{{value}}</th> {% endfor %}
create_done.htmlの全コードは以下の通りです。
{% extends 'kakeibo/base.html' %} {% block content %} <div class="content-wrapper"> <div class="container-fluid"> <!-- Breadcrumbs--> <ol class="breadcrumb"> <li class="breadcrumb-item"> <a href="{% url 'kakeibo:kakeibo_list' %}">TOP</a> </li> <li class="breadcrumb-item active">家計簿アプリ</li> </ol> <!-- Example DataTables Card--> <div class="card mb-3"> <div class="card-header"> <i class="fa fa-server"></i> <b>家計簿アプリ</b></div> <div class="card-body"> <div class="alert alert-info" role="alert">データ登録が正常終了しました。</div> <h3>登録されたデータ</h3> <table class="table table-striped"> <thead> <tr> <th>PK番号</th> <th>カテゴリ名</th> <th>金額</th> <th>メモ</th> </tr> </thead> <tbody> <tr> {% for key, value in contents.items%} <th>{{value}}</th> {% endfor %} </tr> </tbody> </table> {% endblock content %}
以上で設定は完了です。
新規データ登録処理が完了すると、以下のように登録されたレコードが表示できるようになります。
もっとスマートなやり方がありそうなのですが、こんなやり方もあるというくらいで参考にしていただければ幸いです。