如何通过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
相关产品推荐
相关产品推荐

