diff --git a/AUTHORS.rst b/AUTHORS.rst index e2f11046c..87ecfcc41 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -40,6 +40,7 @@ Authors - Michael England - Gregory Bataille - Jesse Shapiro +- Mathieu Hentges Background ========== diff --git a/CHANGES.rst b/CHANGES.rst index de2c97fda..fc3d71042 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,7 @@ Unreleased ---------- - Use get_queryset rather than model.objects in history_view. (gh-303) - Change ugettext calls in models.py to ugettext_lazy +- Add ability to display inlines in the admin history form view 1.9.0 (2017-06-11) ------------------ diff --git a/simple_history/admin.py b/simple_history/admin.py index 70c6ac873..bb7410a35 100644 --- a/simple_history/admin.py +++ b/simple_history/admin.py @@ -154,6 +154,32 @@ def history_form_view(self, request, object_id, version_id): model_name = original_opts.model_name url_triplet = self.admin_site.name, original_opts.app_label, model_name + + inline_instances = self.get_inline_instances(request, obj) + prefixes = {} + formset = [] + + for FormSet, inline in self.get_admin_formsets_with_inline( + *[request]): + prefix = FormSet.get_default_prefix() + prefixes[prefix] = prefixes.get(prefix, 0) + 1 + if prefixes[prefix] != 1 or not prefix: + prefix = "%s-%s" % (prefix, prefixes[prefix]) + formset_params = { + 'instance': obj, + 'prefix': prefix, + 'queryset': inline.get_queryset(request), + } + if request.method == 'POST': + formset_params.update({ + 'data': request.POST.copy(), + 'files': request.FILES, + 'save_as_new': '_saveasnew' in request.POST + }) + formset.append(FormSet(**formset_params)) + + inline_formsets = self.get_admin_inline_formsets( + request, formset, inline_instances, obj) context = { 'title': _('Revert %s') % force_text(obj), 'adminform': admin_form, @@ -170,6 +196,7 @@ def history_form_view(self, request, object_id, version_id): 'history_url': reverse('%s:%s_%s_history' % url_triplet, args=(obj.pk,)), 'change_history': change_history, + 'inline_admin_formsets': inline_formsets, # Context variables copied from render_change_form 'add': False, @@ -190,7 +217,33 @@ def history_form_view(self, request, object_id, version_id): extra_kwargs = {} if get_complete_version() < (1, 8): extra_kwargs['current_app'] = request.current_app - return render(request, self.object_history_form_template, context, **extra_kwargs) + return render(request, + self.object_history_form_template, + context, + **extra_kwargs) + + def get_admin_inline_formsets(self, + request, + formsets, + inline_instances, + obj=None): + """ Django < 1.7 """ + inline_admin_formsets = [] + for inline, formset in zip(inline_instances, formsets): + fieldsets = list(inline.get_fieldsets(request, obj)) + readonly = list(inline.get_readonly_fields(request, obj)) + prepopulated = dict(inline.get_prepopulated_fields(request, obj)) + inline_admin_formset = helpers.InlineAdminFormSet( + inline, formset, fieldsets, prepopulated, readonly, + model_admin=self, + ) + inline_admin_formsets.append(inline_admin_formset) + return inline_admin_formsets + + def get_admin_formsets_with_inline(self, request, obj=None): + """ Django < 1.7 """ + for inline in self.get_inline_instances(request, obj): + yield inline.get_formset(request, obj), inline def save_model(self, request, obj, form, change): """Set special model attribute to user for reference after save""" diff --git a/simple_history/tests/admin.py b/simple_history/tests/admin.py index a0ac13204..f42b7a3f5 100644 --- a/simple_history/tests/admin.py +++ b/simple_history/tests/admin.py @@ -6,6 +6,11 @@ from .models import Poll, Choice, Person, Book, Document, Paper, Employee +class ChoiceInline(admin.TabularInline): + model = Choice + extra = 1 + + class PersonAdmin(SimpleHistoryAdmin): def has_change_permission(self, request, obj=None): return False @@ -15,10 +20,13 @@ class ChoiceAdmin(SimpleHistoryAdmin): history_list_display = ['votes'] -admin.site.register(Poll, SimpleHistoryAdmin) +class PollAdmin(SimpleHistoryAdmin): + inlines = [ChoiceInline, ChoiceInline] + admin.site.register(Choice, ChoiceAdmin) admin.site.register(Person, PersonAdmin) admin.site.register(Book, SimpleHistoryAdmin) admin.site.register(Document, SimpleHistoryAdmin) admin.site.register(Paper, SimpleHistoryAdmin) admin.site.register(Employee, SimpleHistoryAdmin) +admin.site.register(Poll, PollAdmin) diff --git a/simple_history/tests/tests/test_admin.py b/simple_history/tests/tests/test_admin.py index 04b18e5a4..4b40046d7 100644 --- a/simple_history/tests/tests/test_admin.py +++ b/simple_history/tests/tests/test_admin.py @@ -412,7 +412,7 @@ def test_history_form_view_without_getting_history(self): # Verify this is set for original object 'original': poll, 'change_history': False, - + 'inline_admin_formsets': [], 'title': 'Revert %s' % force_text(poll), 'adminform': ANY, 'object_id': poll.id, @@ -466,7 +466,7 @@ def test_history_form_view_getting_history(self): # Verify this is set for history object not poll object 'original': history.instance, 'change_history': True, - + 'inline_admin_formsets': [], 'title': 'Revert %s' % force_text(history.instance), 'adminform': ANY, 'object_id': poll.id, @@ -521,6 +521,7 @@ def test_history_form_view_getting_history_with_setting_off(self): # Verify this is set for history object not poll object 'original': poll, 'change_history': False, + 'inline_admin_formsets': [], 'title': 'Revert %s' % force_text(poll), 'adminform': ANY,