【Django】CreateView で登録完了直後に該当レコードの詳細画面に飛ばす方法|get_success_url 実装

スポンサードリンク



Django · CreateView · 登録後に該当レコードを表示

録完了直後に「今登録したレコードの詳細画面」を表示したい — 業務アプリでよくある UX 要件です。Django の CreateView はデフォルトでは success_url に固定リダイレクトしますが、get_success_url() をオーバーライドして新規作成された self.object.pk を含む URL に飛ばすことで、登録 → 即詳細表示のフローが実現できます。本記事ではその実装パターンを解説します。

この記事では、DjangoのCreateViewを使ったデータ登録処理の完了時に、処理結果として登録したデータレコードを表示する方法を紹介します。

<参考デモ動画>

 

user@sinyblog:~/article 01_section_1.md実装手順

models.py

以下のようなモデルを前提に説明していきます。

python


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を返すようにします。

python


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パターンの設定は以下のようにします。

python


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>/'のように指定します。

python


path('create_done/<int:pk>/<category>/<int:money>/<memo>/', views.create_done, name='create_done'),#設定箇所

 

forms.py

ModelFormを使って登録画面用のフォームを定義します。

普通のフォーム定義なので特に難しい部分はないと思います。

python


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を指定します。

python


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)が呼び出されます。

python


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に格納していきます。

python


contents = {}

for key, val in kwargs.items():

    contents[key] = val

 

最後に、以下の通りreturn renderにcontentsを指定することでテンプレート側に登録されたレコード情報を渡してあげます。

python


return render(request, 'kakeibo/create_done.html',{

        'contents': contents,

    })

 

テンプレート

最後に、テンプレート側で辞書型データcontentsを受け取り、値を表示してあげます。

python


 {% for key, value in contents.items%}

    <th>{{value}}</th>

 {% endfor %}

 

create_done.htmlの全コードは以下の通りです。

python


{% 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 %}

 

以上で設定は完了です。

新規データ登録処理が完了すると、以下のように登録されたレコードが表示できるようになります。

もっとスマートなやり方がありそうなのですが、こんなやり方もあるというくらいで参考にしていただければ幸いです。

 

おすすめの記事