You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过django-simple-history在Django Admin中展示某模型所有实例的历史记录?

如何通过django-simple-history在Django Admin中展示某模型所有实例的历史记录?

我来给你分享两个实用的方案,都是在Django Admin里实现展示所有实例历史记录的好办法👇

方案一:直接注册自动生成的历史模型到Admin

这是最省心的方法,因为django-simple-history会自动为你的模型创建对应的历史模型(比如TestModel对应的就是HistoricalTestModel),我们只需要把这个自动生成的模型注册到Admin就行,完全不用自己额外定义模型。

具体代码如下:

from django.contrib import admin
from .models import TestModel

# 直接通过TestModel.history.model拿到自动生成的历史模型
HistoricalTestModel = TestModel.history.model

class HistoricalTestModelAdmin(admin.ModelAdmin):
    # 自定义要展示的字段,你可以根据自己的需求调整
    list_display = ('history_id', 'title', 'history_date', 'history_user', 'history_type')
    # 添加筛选器,方便按时间、操作人、操作类型筛选
    list_filter = ('history_date', 'history_user', 'history_type')
    # 支持按标题搜索历史记录
    search_fields = ('title',)

# 注册原模型和历史模型到Admin
admin.site.register(TestModel, TestModelAdmin)
admin.site.register(HistoricalTestModel, HistoricalTestModelAdmin)

这个方案的好处是零额外开发成本,直接复用Django Admin自带的列表、筛选、搜索、分页功能,用户体验和原生Admin完全一致,非常适合快速实现需求。

方案二:在现有模型Admin中添加自定义视图

如果你希望所有操作都在原模型的Admin页面下完成,不想让用户切换到其他模型入口,可以用这个方法——在TestModelAdmin里新增一个自定义视图,专门展示所有历史记录。

步骤1:修改TestModelAdmin,添加自定义URL和视图

from django.contrib import admin
from django.shortcuts import render
from .models import TestModel
from django.urls import path

class TestModelAdmin(admin.ModelAdmin):
    list_display = ['title']
    # 自定义列表页面模板,后面要加一个跳转按钮
    change_list_template = 'admin/testmodel_change_list.html'

    def get_urls(self):
        # 把自定义URL加到原有的Admin URL前面
        urls = super().get_urls()
        custom_urls = [
            path(
                'all-history/',
                # 用admin_view包装,确保只有管理员能访问
                self.admin_site.admin_view(self.all_history_view),
                name='testmodel-all-history',
            ),
        ]
        return custom_urls + urls

    def all_history_view(self, request):
        # 查询所有历史记录,按修改时间倒序排列
        history_records = TestModel.history.all().order_by('-history_date')
        # 准备渲染模板的上下文数据
        context = {
            **self.admin_site.each_context(request),
            'title': '所有TestModel历史记录',
            'history_records': history_records,
            # 保留Admin的面包屑导航,让页面风格统一
            'opts': self.model._meta,
        }
        # 渲染自定义的历史记录列表模板
        return render(request, 'admin/testmodel_all_history.html', context)

admin.site.register(TestModel, TestModelAdmin)

步骤2:创建历史记录列表的模板

在你的模板目录下创建templates/admin/testmodel_all_history.html,可以参考Django Admin的风格来写,示例如下:

{% extends "admin/base_site.html" %}
{% block content %}
<div class="module">
    <h2>{{ title }}</h2>
    <table style="width:100%; border-collapse: collapse;">
        <thead>
            <tr style="border-bottom: 2px solid #ccc;">
                <th style="padding: 8px;">历史记录ID</th>
                <th style="padding: 8px;">标题</th>
                <th style="padding: 8px;">修改时间</th>
                <th style="padding: 8px;">操作人</th>
                <th style="padding: 8px;">操作类型</th>
            </tr>
        </thead>
        <tbody>
            {% for record in history_records %}
            <tr style="border-bottom: 1px solid #eee;">
                <td style="padding: 8px;">{{ record.history_id }}</td>
                <td style="padding: 8px;">{{ record.title }}</td>
                <td style="padding: 8px;">{{ record.history_date }}</td>
                <td style="padding: 8px;">{{ record.history_user|default:"未知用户" }}</td>
                <td style="padding: 8px;">
                    {% if record.history_type == '+' %}新增{% elif record.history_type == '~' %}修改{% elif record.history_type == '-' %}删除{% endif %}
                </td>
            </tr>
            {% empty %}
            <tr><td colspan="5" style="padding: 16px; text-align: center;">暂无历史记录</td></tr>
            {% endfor %}
        </tbody>
    </table>
</div>
{% endblock %}

步骤3:在原模型列表页面添加跳转按钮

创建templates/admin/testmodel_change_list.html,给原模型的列表页面加一个“查看所有历史记录”的按钮:

{% extends "admin/change_list.html" %}
{% block object-tools %}
    <div style="margin-bottom: 10px;">
        <a href="{% url 'admin:testmodel-all-history' %}" class="button">查看所有历史记录</a>
    </div>
    {{ block.super }}
{% endblock %}

这个方案的好处是和原模型的Admin完全整合,用户操作路径更短,体验更连贯。

方案选择建议

  • 如果追求快速实现,不想写额外模板,优先选方案一,自带的Admin功能足够用;
  • 如果希望用户不用切换模型页面,操作更顺畅,就选方案二。

备注:内容来源于stack exchange,提问作者ValZhu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:54:29