Skip to content

Commit

Permalink
Fixed #27302 -- Fixed ModelAdmin.construct_change_message() changed f…
Browse files Browse the repository at this point in the history
…ield detection

Thanks Ramiro Morales for the report and Tim Graham for the review.
  • Loading branch information
claudep committed Oct 1, 2016
1 parent aa7dc2d commit 67eee5e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 26 deletions.
48 changes: 24 additions & 24 deletions django/contrib/admin/options.py
Expand Up @@ -929,7 +929,6 @@ def get_preserved_filters(self, request):
return urlencode({'_changelist_filters': preserved_filters})
return ''

@translation_override(None)
def construct_change_message(self, request, form, formsets, add=False):
"""
Construct a JSON structure describing changes from a changed object.
Expand All @@ -943,29 +942,30 @@ def construct_change_message(self, request, form, formsets, add=False):
change_message.append({'changed': {'fields': form.changed_data}})

if formsets:
for formset in formsets:
for added_object in formset.new_objects:
change_message.append({
'added': {
'name': force_text(added_object._meta.verbose_name),
'object': force_text(added_object),
}
})
for changed_object, changed_fields in formset.changed_objects:
change_message.append({
'changed': {
'name': force_text(changed_object._meta.verbose_name),
'object': force_text(changed_object),
'fields': changed_fields,
}
})
for deleted_object in formset.deleted_objects:
change_message.append({
'deleted': {
'name': force_text(deleted_object._meta.verbose_name),
'object': force_text(deleted_object),
}
})
with translation_override(None):
for formset in formsets:
for added_object in formset.new_objects:
change_message.append({
'added': {
'name': force_text(added_object._meta.verbose_name),
'object': force_text(added_object),
}
})
for changed_object, changed_fields in formset.changed_objects:
change_message.append({
'changed': {
'name': force_text(changed_object._meta.verbose_name),
'object': force_text(changed_object),
'fields': changed_fields,
}
})
for deleted_object in formset.deleted_objects:
change_message.append({
'deleted': {
'name': force_text(deleted_object._meta.verbose_name),
'object': force_text(deleted_object),
}
})
return change_message

def message_user(self, request, message, level=messages.INFO, extra_tags='',
Expand Down
3 changes: 3 additions & 0 deletions docs/releases/1.10.2.txt
Expand Up @@ -25,3 +25,6 @@ Bugfixes

* Fixed a crash in ``runserver`` logging during a "Broken pipe" error
(:ticket:`27271`).

* Fixed a regression where unchanged localized date/time fields were listed as
changed in the admin's model history messages (:ticket:`27302`).
20 changes: 18 additions & 2 deletions tests/admin_utils/test_logentry.py
Expand Up @@ -25,7 +25,7 @@ def setUp(self):
self.a1 = Article.objects.create(
site=self.site,
title="Title",
created=datetime(2008, 3, 18, 11, 54),
created=datetime(2008, 3, 12, 11, 54),
)
content_type_pk = ContentType.objects.get_for_model(Article).pk
LogEntry.objects.log_action(
Expand All @@ -51,7 +51,7 @@ def test_logentry_change_message(self):
"""
post_data = {
'site': self.site.pk, 'title': 'Changed', 'hist': 'Some content',
'created_0': '2008-03-18', 'created_1': '11:54',
'created_0': '2008-03-12', 'created_1': '11:54',
}
change_url = reverse('admin:admin_utils_article_change', args=[quote(self.a1.pk)])
response = self.client.post(change_url, post_data)
Expand All @@ -70,6 +70,22 @@ def test_logentry_change_message(self):
with translation.override('fr'):
self.assertEqual(logentry.get_change_message(), 'Ajout.')

@override_settings(USE_L10N=True)
def test_logentry_change_message_localized_datetime_input(self):
"""
Localized date/time inputs shouldn't affect changed form data detection.
"""
post_data = {
'site': self.site.pk, 'title': 'Changed', 'hist': 'Some content',
'created_0': '12/03/2008', 'created_1': '11:54',
}
with translation.override('fr'):
change_url = reverse('admin:admin_utils_article_change', args=[quote(self.a1.pk)])
response = self.client.post(change_url, post_data)
self.assertRedirects(response, reverse('admin:admin_utils_article_changelist'))
logentry = LogEntry.objects.filter(content_type__model__iexact='article').latest('id')
self.assertEqual(logentry.get_change_message(), 'Changed title and hist.')

def test_logentry_change_message_formsets(self):
"""
All messages for changed formsets are logged in a change message.
Expand Down

0 comments on commit 67eee5e

Please sign in to comment.