Fixed #16327 -- Redirected "Save as new" to change view instead of the changelist.
This commit is contained in:
parent
cb65e62c84
commit
08cd6a0e56
|
@ -487,6 +487,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
search_fields = ()
|
search_fields = ()
|
||||||
date_hierarchy = None
|
date_hierarchy = None
|
||||||
save_as = False
|
save_as = False
|
||||||
|
save_as_continue = True
|
||||||
save_on_top = False
|
save_on_top = False
|
||||||
paginator = Paginator
|
paginator = Paginator
|
||||||
preserve_filters = True
|
preserve_filters = True
|
||||||
|
@ -1102,7 +1103,11 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
'popup_response_data': popup_response_data,
|
'popup_response_data': popup_response_data,
|
||||||
})
|
})
|
||||||
|
|
||||||
elif "_continue" in request.POST:
|
elif "_continue" in request.POST or (
|
||||||
|
# Redirecting after "Save as new".
|
||||||
|
"_saveasnew" in request.POST and self.save_as_continue and
|
||||||
|
self.has_change_permission(request, obj)
|
||||||
|
):
|
||||||
msg = format_html(
|
msg = format_html(
|
||||||
_('The {name} "{obj}" was added successfully. You may edit it again below.'),
|
_('The {name} "{obj}" was added successfully. You may edit it again below.'),
|
||||||
**msg_dict
|
**msg_dict
|
||||||
|
|
|
@ -1146,6 +1146,16 @@ subclass::
|
||||||
|
|
||||||
By default, ``save_as`` is set to ``False``.
|
By default, ``save_as`` is set to ``False``.
|
||||||
|
|
||||||
|
.. attribute:: ModelAdmin.save_as_continue
|
||||||
|
|
||||||
|
.. versionadded:: 1.10
|
||||||
|
|
||||||
|
When :attr:`save_as=True <save_as>`, the default redirect after saving the
|
||||||
|
new object is to the change view for that object. If you set
|
||||||
|
``save_as_continue=False``, the redirect will be to the changelist view.
|
||||||
|
|
||||||
|
By default, ``save_as_continue`` is set to ``True``.
|
||||||
|
|
||||||
.. attribute:: ModelAdmin.save_on_top
|
.. attribute:: ModelAdmin.save_on_top
|
||||||
|
|
||||||
Set ``save_on_top`` to add save buttons across the top of your admin change
|
Set ``save_on_top`` to add save buttons across the top of your admin change
|
||||||
|
|
|
@ -753,6 +753,13 @@ Miscellaneous
|
||||||
model, you must convert them to attributes or properties as described in
|
model, you must convert them to attributes or properties as described in
|
||||||
:ref:`the deprecation note <user-is-auth-anon-deprecation>`.
|
:ref:`the deprecation note <user-is-auth-anon-deprecation>`.
|
||||||
|
|
||||||
|
* When using :attr:`ModelAdmin.save_as=True
|
||||||
|
<django.contrib.admin.ModelAdmin.save_as>`, the "Save as new" button now
|
||||||
|
redirects to the change view for the new object instead of to the model's
|
||||||
|
changelist. If you need the previous behavior, set the new
|
||||||
|
:attr:`ModelAdmin.save_as_continue
|
||||||
|
<django.contrib.admin.ModelAdmin.save_as_continue>` attribute to ``False``.
|
||||||
|
|
||||||
.. _deprecated-features-1.10:
|
.. _deprecated-features-1.10:
|
||||||
|
|
||||||
Features deprecated in 1.10
|
Features deprecated in 1.10
|
||||||
|
|
|
@ -1013,6 +1013,7 @@ site2.register(
|
||||||
list_editable=['parent'],
|
list_editable=['parent'],
|
||||||
raw_id_fields=['parent'],
|
raw_id_fields=['parent'],
|
||||||
)
|
)
|
||||||
|
site2.register(Person, save_as_continue=False)
|
||||||
|
|
||||||
site7 = admin.AdminSite(name="admin7")
|
site7 = admin.AdminSite(name="admin7")
|
||||||
site7.register(Article, ArticleAdmin2)
|
site7.register(Article, ArticleAdmin2)
|
||||||
|
|
|
@ -1119,9 +1119,23 @@ class SaveAsTests(TestCase):
|
||||||
def test_save_as_duplication(self):
|
def test_save_as_duplication(self):
|
||||||
"""Ensure save as actually creates a new person"""
|
"""Ensure save as actually creates a new person"""
|
||||||
post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 1, 'age': 42}
|
post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 1, 'age': 42}
|
||||||
self.client.post(reverse('admin:admin_views_person_change', args=(self.per1.pk,)), post_data)
|
response = self.client.post(reverse('admin:admin_views_person_change', args=(self.per1.pk,)), post_data)
|
||||||
self.assertEqual(len(Person.objects.filter(name='John M')), 1)
|
self.assertEqual(len(Person.objects.filter(name='John M')), 1)
|
||||||
self.assertEqual(len(Person.objects.filter(id=self.per1.pk)), 1)
|
self.assertEqual(len(Person.objects.filter(id=self.per1.pk)), 1)
|
||||||
|
new_person = Person.objects.latest('id')
|
||||||
|
self.assertRedirects(response, reverse('admin:admin_views_person_change', args=(new_person.pk,)))
|
||||||
|
|
||||||
|
def test_save_as_continue_false(self):
|
||||||
|
"""
|
||||||
|
Saving a new object using "Save as new" redirects to the changelist
|
||||||
|
instead of the change view when ModelAdmin.save_as_continue=False.
|
||||||
|
"""
|
||||||
|
post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 1, 'age': 42}
|
||||||
|
url = reverse('admin:admin_views_person_change', args=(self.per1.pk,), current_app=site2.name)
|
||||||
|
response = self.client.post(url, post_data)
|
||||||
|
self.assertEqual(len(Person.objects.filter(name='John M')), 1)
|
||||||
|
self.assertEqual(len(Person.objects.filter(id=self.per1.pk)), 1)
|
||||||
|
self.assertRedirects(response, reverse('admin:admin_views_person_changelist', current_app=site2.name))
|
||||||
|
|
||||||
def test_save_as_new_with_validation_errors(self):
|
def test_save_as_new_with_validation_errors(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1689,6 +1703,15 @@ class AdminViewPermissionsTest(TestCase):
|
||||||
self.assertEqual(post.status_code, 403)
|
self.assertEqual(post.status_code, 403)
|
||||||
self.assertEqual(Article.objects.count(), article_count)
|
self.assertEqual(Article.objects.count(), article_count)
|
||||||
|
|
||||||
|
# User with both add and change permissions should be redirected to the
|
||||||
|
# change page for the newly created object.
|
||||||
|
article_count = Article.objects.count()
|
||||||
|
self.client.force_login(self.superuser)
|
||||||
|
post = self.client.post(article_change_url, change_dict_save_as_new)
|
||||||
|
self.assertEqual(Article.objects.count(), article_count + 1)
|
||||||
|
new_article = Article.objects.latest('id')
|
||||||
|
self.assertRedirects(post, reverse('admin:admin_views_article_change', args=(new_article.pk,)))
|
||||||
|
|
||||||
def test_delete_view(self):
|
def test_delete_view(self):
|
||||||
"""Delete view should restrict access and actually delete items."""
|
"""Delete view should restrict access and actually delete items."""
|
||||||
delete_dict = {'post': 'yes'}
|
delete_dict = {'post': 'yes'}
|
||||||
|
|
Loading…
Reference in New Issue