Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Unreleased
- Dropped support for Django 4.0, which reached end-of-life on 2023-04-01 (gh-1202)
- Added support for Django 4.2 (gh-1202)
- Made ``bulk_update_with_history()`` return the number of model rows updated (gh-1206)
- Added pagination and filtering to SimpleHistoryAdmin (gh-1211)

3.3.0 (2023-03-08)
------------------
Expand Down
24 changes: 23 additions & 1 deletion docs/admin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ An example of admin integration for the ``Poll`` and ``Choice`` models:

Changing a history-tracked model from the admin interface will automatically record the user who made the change (see :doc:`/user_tracking`).

Changing the number of histoical records shown in admin history list view
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

By default, the history list view in admin shows the last 50 records. You can change this by adding a `list_per_page` attribute to the admin class.


Displaying custom columns in the admin history list view
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -49,7 +54,24 @@ By default, the history log displays one line per change containing

You can add other columns (for example the object's status to see
how it evolved) by adding a ``history_list_display`` array of fields to the
admin class
admin class.

.. code-block:: python

from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin
from .models import Poll, Choice

class PollHistoryAdmin(SimpleHistoryAdmin):
history_list_display = ["status"]
list_display = ["id", "name", "status"]
search_fields = ['name', 'user__username']
list_per_page = 100

admin.site.register(Poll, PollHistoryAdmin)
admin.site.register(Choice, SimpleHistoryAdmin)

..

.. code-block:: python

Expand Down
10 changes: 8 additions & 2 deletions simple_history/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.contrib.admin.utils import unquote
from django.contrib.auth import get_permission_codename, get_user_model
from django.core.exceptions import PermissionDenied
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, render
from django.urls import re_path, reverse
from django.utils.encoding import force_str
Expand All @@ -21,6 +22,7 @@
class SimpleHistoryAdmin(admin.ModelAdmin):
object_history_template = "simple_history/object_history.html"
object_history_form_template = "simple_history/object_history_form.html"
list_per_page = 50

def get_urls(self):
"""Returns the additional urls used by the Reversion admin."""
Expand Down Expand Up @@ -60,14 +62,18 @@ def history_view(self, request, object_id, extra_context=None):
except action_list.model.DoesNotExist:
raise http.Http404

paginator = Paginator(action_list, self.list_per_page)
page_number = request.GET.get("page", 1)
action_list_page = paginator.get_page(page_number)

if not self.has_view_history_or_change_history_permission(request, obj):
raise PermissionDenied

# Set attribute on each action_list entry from admin methods
for history_list_entry in history_list_display:
value_for_entry = getattr(self, history_list_entry, None)
if value_for_entry and callable(value_for_entry):
for list_entry in action_list:
for list_entry in action_list_page.object_list:
setattr(list_entry, history_list_entry, value_for_entry(list_entry))

content_type = self.content_type_model_cls.objects.get_for_model(
Expand All @@ -80,7 +86,7 @@ def history_view(self, request, object_id, extra_context=None):
)
context = {
"title": self.history_view_title(request, obj),
"action_list": action_list,
"action_list": action_list_page,
"module_name": capfirst(force_str(opts.verbose_name_plural)),
"object": obj,
"root_path": getattr(self.admin_site, "root_path", None),
Expand Down