【Django】Adminで自作アクションの確認画面を追加

django-admin-action-confirm-title CODE

便利でカスタマイズ可能なAdminサイトのアクションですが、削除アクションと同じように確認画面があれば非常に便利です。

本記事では、管理画面に自作アクションの確認画面を追加する方法を紹介します。

こんな感じの確認画面をAdmin内に作ります↓

Django管理画面にアクションの確認画面

Adminアクションの追加方法は以下の記事へ↓

管理画面にページを追加する方法は以下の記事へ↓

なお、この記事で使うPython・Djangoのバージョンは以下のとおりです。

Python 3.7
Django 2.2.5

1.確認画面へ遷移するアクションを追加

以下の様なmodels.pyとadmin.pyを用意。

from django.db import models

class Book(models.Model):
    title = models.CharField(verbose_name='タイトル', max_length=255)
    class Meta:
        db_table = 'book'
        verbose_name = verbose_name_plural = "書籍"
from django.contrib import admin
from .models import Book

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('id', 'title')

 

管理画面はこんな感じ↓

Django管理画面にアクションの確認画面2

今回用意するアクションは、選択した本オブジェクトのタイトルの前に【必見】を付けるというものです。

 

まず、確認画面へ遷移するアクションを追加。

from django.contrib import admin
from django.template.response import TemplateResponse
from .models import Book

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('id', 'title')
    actions = ['change_title_action']

    def change_title_action(self, request, queryset):
        return TemplateResponse(
            request,
            'admin/app/book/change_title_confirm.html',
            {'queryset': queryset}
        )
    change_title_action.short_description = 'タイトルの前に【必見】を追加'

選択したオブジェクト(  queryset )をテンプレートに渡すだけのアクションです。

 

2.確認画面のテンプレートを作成

確認画面では、選択した本オブジェクトをサーバーから受け取り、オブジェクトのIDとタイトルを表示させます。

{% extends "admin/base_site.html" %}

{% block content %}
    よろしいですか?<span><</span>br>
    選択した以下の本のタイトルを変更しますか?<span><</span>br>

    {% for obj in queryset %}
        ID:{{obj.id}} タイトル:{{obj.title}}
    {% endfor %}

    <span><</span>form method="post" action="change_title/">
        {% csrf_token %}
        {% for obj in queryset %}
            <span><</span>input type="hidden" name="id" value="{{ obj.id }}">
        {% endfor %}
        <span><</span>input type="submit" value="はい">
        <span><</span>a href="/admin/app/book/" class="button cancel-link">戻る</a>
    </form>
{% endblock %}

submitボタン押下時に処理を行うURLをフォームのactionに定義します。

ここではactionのURLを  change_title としました。

また、サーバー側で処理を行うオブジェクトを特定するためにhiddenでオブジェクトのidをサーバーに送信します。

サーバーにidを送る方法は他にもありますがここでは割愛します。

Django管理画面にアクションの確認画面

こんな感じの確認画面が完成。

3.処理を行う関数を作成

2.で定義したactionのURL(  change_title  )をadminで定義し、URLに紐づく関数を作成します。

...
from django.urls import path
from django.shortcuts import redirect
from .models import Book

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
...
    def get_urls(self):
        urls = super().get_urls()  # デフォルトのadmin urlを呼び出す
        # 追加したいURLと対応するビューを記述
        add_urls = [
            path('change_title/', self.admin_site.admin_view(self.change_title), name="add_page"),
        ]
        return add_urls + urls  # 自作ページのURLを追加。必ずadd_urlsを前に!

    def change_title(self, request):
        ids = request.POST.getlist('id')
        for id in ids:
            book = Book.objects.filter(id=id).first()
            book.title = "【必見】" + book.title
            book.save()
        return redirect('/admin/app/book/')
 get_urls では確認画面から飛んできた  change_title  (正確にはhttps://ドメイン/admin/app/book/ change_title)と処理する関数のルーティングを定義。

今回は、選択した本オブジェクトのタイトルの前に【必見】を付ける change_title という関数を作成しました。

 

処理の流れは、 request.POST.getlist(‘id’) でフォームから送信したオブジェクトのidを取得。

【必見】を付けた後オブジェクトをDBに保存し、  redirect で一覧画面へ戻るという感じです。

 

完成したので動作確認。

Django管理画面にアクションの確認画面3
Django管理画面にアクションの確認画面
Django管理画面にアクションの確認画面

無事確認画面を遷移し、選択したオブジェクトだけが変更されました。

Adminのカスタマイズ楽しい。