Skip to content

Commit 1fb1401

Browse files
committed
Expose change reason to admin form
Fixes #853
1 parent 29108a5 commit 1fb1401

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Unreleased
1515
- Added temporary requirement on ``asgiref>=3.6`` while the minimum required Django
1616
version is lower than 4.2 (gh-1261)
1717
- Small performance optimization of the ``clean-duplicate_history`` command (gh-1015)
18+
- Allow setting change reason through ``SimpleHistoryAdmin``'s change form (gh-1232)
1819

1920
3.4.0 (2023-08-18)
2021
------------------

simple_history/admin.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
from django import http
1+
from django import forms, http
22
from django.apps import apps as django_apps
33
from django.conf import settings
44
from django.contrib import admin
55
from django.contrib.admin import helpers
66
from django.contrib.admin.utils import unquote
77
from django.contrib.auth import get_permission_codename, get_user_model
88
from django.core.exceptions import PermissionDenied
9+
from django.forms import fields
910
from django.shortcuts import get_object_or_404, render
1011
from django.urls import re_path, reverse
1112
from django.utils.encoding import force_str
@@ -224,9 +225,31 @@ def render_history_view(self, request, template, context, **kwargs):
224225

225226
def save_model(self, request, obj, form, change):
226227
"""Set special model attribute to user for reference after save"""
228+
obj._change_reason = form.cleaned_data["history_change_reason"]
227229
obj._history_user = request.user
228230
super().save_model(request, obj, form, change)
229231

232+
class form(forms.ModelForm):
233+
history_change_reason = forms.CharField(required=False)
234+
235+
def get_fields(self, request, obj=None):
236+
return [
237+
field
238+
for field in super().get_fields(request, obj)
239+
if field != "history_change_reason"
240+
]
241+
242+
def get_fieldsets(self, request, obj=None):
243+
return super().get_fieldsets(request, obj) + [
244+
(
245+
"History",
246+
{
247+
"classes": ["collapse"],
248+
"fields": ["history_change_reason"],
249+
},
250+
)
251+
]
252+
230253
@property
231254
def content_type_model_cls(self):
232255
"""Returns the ContentType model class."""

simple_history/tests/tests/test_admin.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,36 @@ def test_history_user_on_save_in_admin(self):
218218
[p.history_user for p in Poll.history.all()], [self.user, self.user]
219219
)
220220

221+
def test_history_change_reason_on_save_in_admin(self):
222+
self.login()
223+
224+
change_reason = "New change reason"
225+
# Ensure polls created via admin interface save correct change reason
226+
poll_data = {
227+
"question": "new poll?",
228+
"pub_date_0": "2012-01-01",
229+
"pub_date_1": "10:00:00",
230+
"change_reason": change_reason,
231+
}
232+
self.client.post(reverse("admin:tests_poll_add"), data=poll_data)
233+
poll = Poll.objects.get()
234+
self.assertEqual(poll.history.get().history_change_reason, change_reason)
235+
236+
237+
change_reason = "Edited change reason"
238+
# Ensure polls modified via admin interface save correct change reason
239+
poll_data = {
240+
"question": "new poll?",
241+
"pub_date_0": "2011-01-01",
242+
"pub_date_1": "10:00:00",
243+
"change_reason": change_reason,
244+
}
245+
self.client.post(reverse("admin:tests_poll_change"), data=poll_data)
246+
poll.refresh_from_db()
247+
self.assertEqual(poll.pub_date_0, "2011-01-01")
248+
self.assertEqual(poll.history.count(), 2)
249+
self.assertEqual(poll.history.latest().history_change_reason, change_reason)
250+
221251
def test_underscore_in_pk(self):
222252
self.login()
223253
book = Book(isbn="9780147_513731")

0 commit comments

Comments
 (0)