Skip to content

Commit

Permalink
Expose change reason to admin form
Browse files Browse the repository at this point in the history
Fixes #853
  • Loading branch information
mjsir911 committed Oct 6, 2023
1 parent 29108a5 commit ba35004
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Unreleased
- Added temporary requirement on ``asgiref>=3.6`` while the minimum required Django
version is lower than 4.2 (gh-1261)
- Small performance optimization of the ``clean-duplicate_history`` command (gh-1015)
- Allow setting change reason through ``SimpleHistoryAdmin``'s change form (gh-1232)

3.4.0 (2023-08-18)
------------------
Expand Down
25 changes: 24 additions & 1 deletion simple_history/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django import http
from django import forms, http
from django.apps import apps as django_apps
from django.conf import settings
from django.contrib import admin
Expand All @@ -17,6 +17,8 @@

SIMPLE_HISTORY_EDIT = getattr(settings, "SIMPLE_HISTORY_EDIT", False)

class HistoryChangeReasonForm(forms.ModelForm):
history_change_reason = forms.CharField(required=False)

class SimpleHistoryAdmin(admin.ModelAdmin):
object_history_template = "simple_history/object_history.html"
Expand Down Expand Up @@ -224,9 +226,30 @@ def render_history_view(self, request, template, context, **kwargs):

def save_model(self, request, obj, form, change):
"""Set special model attribute to user for reference after save"""
obj._change_reason = form.cleaned_data.get("history_change_reason")
obj._history_user = request.user
super().save_model(request, obj, form, change)

form = HistoryChangeReasonForm

def get_fields(self, request, obj=None):
return [
field
for field in super().get_fields(request, obj)
if field != "history_change_reason"
]

def get_fieldsets(self, request, obj=None):
return super().get_fieldsets(request, obj) + ([
(
"History",
{
"classes": ["collapse"],
"fields": ["history_change_reason"],
},
)
] if 'history_change_reason' in self.form.declared_fields else [])

@property
def content_type_model_cls(self):
"""Returns the ContentType model class."""
Expand Down
44 changes: 44 additions & 0 deletions simple_history/tests/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,50 @@ def test_history_user_on_save_in_admin(self):
[p.history_user for p in Poll.history.all()], [self.user, self.user]
)

def test_history_change_reason_on_save_in_admin(self):
self.login()

# Ensure polls created via admin interface save correct change reason
change_reason = "New change reason"
initial_data = poll_data = {
"question": "new poll?",
"pub_date_0": "2012-01-01",
"pub_date_1": "10:00:00",
"history_change_reason": change_reason,
}
self.client.post(reverse("admin:tests_poll_add"), data=poll_data)
poll = Poll.objects.get()
self.assertEqual(poll.history.get().history_change_reason, change_reason)


# Ensure polls modified via admin interface save correct change reason
change_reason = "Edited change reason"
poll_data = {
"question": "new poll?",
"pub_date_0": "2011-01-01",
"pub_date_1": "10:00:00",
"history_change_reason": change_reason,
}
self.client.post(reverse("admin:tests_poll_change", args=[poll.id]), data=poll_data)
poll.refresh_from_db()
self.assertEqual(poll.pub_date.year, 2011)
self.assertEqual(poll.history.count(), 2)
self.assertEqual(poll.history.latest().history_change_reason, change_reason)

# Let's emulate a revert
change_reason = "Revert to history record 0"
response = self.client.get(get_history_url(poll, 0))
form = response.context.get("adminform").form
self.assertEqual(form["history_change_reason"].value(), None) # Always starts empty
self.assertEqual(form["pub_date"].value().year, 2012)

self.client.post(get_history_url(poll, 0), data=initial_data | {"history_change_reason": change_reason})

poll.refresh_from_db()
self.assertEqual(poll.pub_date.year, 2012)
self.assertEqual(poll.history.count(), 3)
self.assertEqual(poll.history.latest().history_change_reason, change_reason)

def test_underscore_in_pk(self):
self.login()
book = Book(isbn="9780147_513731")
Expand Down

0 comments on commit ba35004

Please sign in to comment.