summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/admin/options.py4
-rw-r--r--tests/admin_views/tests.py24
2 files changed, 26 insertions, 2 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index d8d56fd1d5..86da05a7fa 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -11,7 +11,7 @@ from django.contrib.admin import widgets, helpers
from django.contrib.admin import validation
from django.contrib.admin.checks import (BaseModelAdminChecks, ModelAdminChecks,
InlineModelAdminChecks)
-from django.contrib.admin.utils import (unquote, flatten_fieldsets,
+from django.contrib.admin.utils import (quote, unquote, flatten_fieldsets,
get_deleted_objects, model_format_dict, NestedObjects,
lookup_needs_distinct)
from django.contrib.admin.templatetags.admin_static import static
@@ -1100,7 +1100,7 @@ class ModelAdmin(BaseModelAdmin):
if post_url_continue is None:
post_url_continue = reverse('admin:%s_%s_change' %
(opts.app_label, opts.model_name),
- args=(pk_value,),
+ args=(quote(pk_value),),
current_app=self.admin_site.name)
post_url_continue = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url_continue)
return HttpResponseRedirect(post_url_continue)
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index fbea1d49c7..21f1eb818c 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -1779,6 +1779,30 @@ class AdminViewStringPrimaryKeyTest(TestCase):
args=(quote(self.pk),))
self.assertContains(response, '<a href="%s" class="historylink"' % expected_link)
+ def test_redirect_on_add_view_continue_button(self):
+ """As soon as an object is added using "Save and continue editing"
+ button, the user should be redirected to the object's change_view.
+
+ In case primary key is a string containing some special characters
+ like slash or underscore, these characters must be escaped (see #22266)
+ """
+ response = self.client.post(
+ '/test_admin/admin/admin_views/modelwithstringprimarykey/add/',
+ {
+ 'string_pk': '123/history',
+ "_continue": "1", # Save and continue editing
+ }
+ )
+
+ self.assertEqual(response.status_code, 302) # temporary redirect
+ self.assertEqual(
+ response['location'],
+ (
+ 'http://testserver/test_admin/admin/admin_views/'
+ 'modelwithstringprimarykey/123_2Fhistory/' # PK is quoted
+ )
+ )
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class SecureViewTests(TestCase):