Django: admin.ModelAdmin.object_history_template の代替方法とは?
admin.ModelAdmin.object_history_template
は、Django 管理画面におけるオブジェクト履歴表示テンプレートを指定するための属性です。オブジェクト履歴とは、モデルインスタンスに対する変更履歴を記録した機能であり、管理画面から閲覧することができます。
設定方法
admin.ModelAdmin.object_history_template
には、テンプレートファイルのパスを文字列として設定します。テンプレートファイルは、以下のいずれかの方法で指定できます。
- 絶対パス:
/path/to/project/templates/admin/object_history.html
- 相対パス:
templates/admin/object_history.html
- アプリ内パス:
myapp/templates/admin/myapp/MyModel/object_history.html
テンプレートの内容
object_history.html
テンプレートファイルには、オブジェクト履歴情報を表示するための HTML コードを記述します。以下の変数を利用することができます。
new_value
: 変更後の値old_value
: 変更前の値field
: 変更されたフィールドdate
: 変更日時user
: 変更を行ったユーザーchange
: 各履歴レコードobject
: 現在閲覧しているオブジェクトhistory
: オブジェクト履歴情報のリスト
{% extends "admin/base.html" %}
{% block content %}
<h1>オブジェクト履歴</h1>
<table>
<thead>
<tr>
<th>日時</th>
<th>ユーザー</th>
<th>変更内容</th>
</tr>
</thead>
<tbody>
{% for change in history %}
<tr>
<td>{{ change.date|date:"Y-m-d H:i:s" }}</td>
<td>{{ change.user }}</td>
<td>
{{ change.field }}: {{ change.old_value }} → {{ change.new_value }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
- オブジェクト履歴機能は、
django.contrib.admin
アプリで有効にする必要があります。 object_history_template
属性は、ModelAdmin
クラスのget_object_history_template()
メソッドでオーバーライドすることができます。object_history.html
テンプレートファイルが存在しない場合、Django はデフォルトのテンプレートを使用します。
models.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=255)
email = models.EmailField()
admin.py
from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin
from .models import MyModel
class MyModelAdmin(SimpleHistoryAdmin):
list_display = ['name', 'email']
history_list_display = ['name', 'email']
admin.site.register(MyModel, MyModelAdmin)
templates/admin/myapp/MyModel/object_history.html
{% extends "admin/base.html" %}
{% block content %}
<h1>オブジェクト履歴</h1>
<table>
<thead>
<tr>
<th>日時</th>
<th>ユーザー</th>
<th>変更内容</th>
</tr>
</thead>
<tbody>
{% for change in history %}
<tr>
<td>{{ change.date|date:"Y-m-d H:i:s" }}</td>
<td>{{ change.user }}</td>
<td>
{% if change.field == 'name' %}
名前: {{ change.old_value }} → {{ change.new_value }}
{% elif change.field == 'email' %}
メールアドレス: {{ change.old_value }} → {{ change.new_value }}
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
説明
上記のコードでは、以下の処理が行われています。
models.py
でMyModel
モデルを定義します。admin.py
でMyModel
モデルの管理画面設定を定義します。list_display
属性で、管理画面一覧ページに表示するフィールドを指定します。history_list_display
属性で、オブジェクト履歴一覧ページに表示するフィールドを指定します。
templates/admin/myapp/MyModel/object_history.html
で、オブジェクト履歴表示テンプレートを定義します。history
変数を使用して、オブジェクト履歴情報を取得します。change
変数を使用して、各履歴レコードを取得します。user
変数を使用して、変更を行ったユーザーを取得します。date
変数を使用して、変更日時を取得します。field
変数を使用して、変更されたフィールドを取得します。old_value
変数を使用して、変更前の値を取得します。new_value
変数を使用して、変更後の値を取得します。
- オブジェクト履歴機能は、
django.contrib.admin
アプリで有効にする必要があります。
そこで、admin.ModelAdmin.object_history_template
属性の代替方法として、以下の方法が考えられます。
SimpleHistoryAdmin を利用する
django-simple-history
パッケージには、SimpleHistoryAdmin
クラスが用意されています。このクラスを使用すると、テンプレートファイルを自分で作成することなく、デフォルトのオブジェクト履歴表示テンプレートを利用することができます。
設定方法
from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin
from .models import MyModel
class MyModelAdmin(SimpleHistoryAdmin):
list_display = ['name', 'email']
history_list_display = ['name', 'email']
admin.site.register(MyModel, MyModelAdmin)
メリット
- カスタマイズも可能
- デフォルトのテンプレートが用意されている
- テンプレートファイルを自分で作成する必要がない
デメリット
- デフォルトのテンプレートが気に入らない場合は、カスタマイズが必要
django-simple-history
パッケージをインストールする必要がある
シグナルを利用する
Django は、オブジェクトが作成、更新、削除された際にシグナルを発行します。これらのシグナルを利用して、オブジェクト履歴情報を取得し、独自の表示ロジックを実装することができます。
シグナル例
post_delete
: オブジェクトが削除された後に発行されるシグナルpost_save
: オブジェクトが保存された後に発行されるシグナル
実装例
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from .models import MyModel
@receiver(post_save, sender=MyModel)
def save_history(sender, instance, created, **kwargs):
# オブジェクト履歴情報を保存する処理
@receiver(post_delete, sender=MyModel)
def delete_history(sender, instance, **kwargs):
# オブジェクト履歴情報を削除する処理
メリット
- 柔軟な表示ロジックを実装できる
- テンプレートファイルを自分で作成する必要がない
デメリット
- 複雑なロジックを実装する場合は、コードが冗長になりやすい
- シグナルの処理を自分で書く必要がある
Django には、オブジェクト履歴機能を拡張するサードパーティ製ライブラリがいくつか存在します。これらのライブラリを利用すると、テンプレートファイルを自分で作成することなく、より高度なオブジェクト履歴機能を利用することができます。
ライブラリ例
django-versioned-admin
: オブジェクト履歴に基づいてバージョン管理を行うライブラリdjango-admin-change-list
: 管理画面一覧ページにオブジェクト履歴情報を表示するライブラリ
メリット
- より高度なオブジェクト履歴機能を利用できる
- テンプレートファイルを自分で作成する必要がない
デメリット
- ライブラリの使用方法を覚える必要がある
- ライブラリをインストールする必要がある
admin.ModelAdmin.object_history_template
属性以外にも、オブジェクト履歴を表示する方法はいくつかあります。それぞれの方法にはメリットとデメリットがあるので、ご自身のプロジェクトに合った方法を選択してください。