Loading django/contrib/admin/options.py +6 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ from django.utils.safestring import mark_safe from django.utils.text import capfirst, get_text_list from django.utils.translation import string_concat, ugettext as _, ungettext from django.views.decorators.csrf import csrf_protect from django.views.generic import RedirectView IS_POPUP_VAR = '_popup' TO_FIELD_VAR = '_to_field' Loading Loading @@ -554,7 +555,11 @@ class ModelAdmin(BaseModelAdmin): url(r'^add/$', wrap(self.add_view), name='%s_%s_add' % info), url(r'^(.+)/history/$', wrap(self.history_view), name='%s_%s_history' % info), url(r'^(.+)/delete/$', wrap(self.delete_view), name='%s_%s_delete' % info), url(r'^(.+)/$', wrap(self.change_view), name='%s_%s_change' % info), url(r'^(.+)/change/$', wrap(self.change_view), name='%s_%s_change' % info), # For backwards compatibility (was the change url before 1.9) url(r'^(.+)/$', wrap(RedirectView.as_view( pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info) ))), ] return urlpatterns Loading docs/releases/1.9.txt +8 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,14 @@ Minor features * Admin views now have ``model_admin`` or ``admin_site`` attributes. * The URL of the admin change view has been changed (was at ``/admin/<app>/<model>/<pk>/`` by default and is now at ``/admin/<app>/<model>/<pk>/change/``). This should not affect your application unless you have hardcoded admin URLs. In that case, replace those links by :ref:`reversing admin URLs <admin-reverse-urls>` instead. Note that the old URL still redirects to the new one for backwards compatibility, but it may be removed in a future version. :mod:`django.contrib.auth` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading tests/admin_custom_urls/tests.py +0 −5 Original line number Diff line number Diff line Loading @@ -61,11 +61,6 @@ class AdminCustomUrlsTest(TestCase): """ # Should get the change_view for model instance with PK 'add', not show # the add_view response = self.client.get('/admin/admin_custom_urls/action/add/') self.assertEqual(response.status_code, 200) self.assertContains(response, 'Change action') # Ditto, but use reverse() to build the URL url = reverse('admin:%s_action_change' % Action._meta.app_label, args=(quote('add'),)) response = self.client.get(url) Loading tests/admin_views/admin.py +1 −1 Original line number Diff line number Diff line Loading @@ -693,7 +693,7 @@ class UnchangeableObjectAdmin(admin.ModelAdmin): def get_urls(self): # Disable change_view, but leave other urls untouched urlpatterns = super(UnchangeableObjectAdmin, self).get_urls() return [p for p in urlpatterns if not p.name.endswith("_change")] return [p for p in urlpatterns if p.name and not p.name.endswith("_change")] def callable_on_unknown(obj): Loading tests/admin_views/tests.py +16 −2 Original line number Diff line number Diff line Loading @@ -137,6 +137,15 @@ class AdminViewBasicTest(AdminViewBasicTestCase): response = self.client.get(reverse('admin:admin_views_section_change', args=('abc',))) self.assertEqual(response.status_code, 404) def test_basic_edit_GET_old_url_redirect(self): """ The change URL changed in Django 1.9, but the old one still redirects. """ response = self.client.get( reverse('admin:admin_views_section_change', args=(1,)).replace('change/', '') ) self.assertRedirects(response, reverse('admin:admin_views_section_change', args=(1,))) def test_basic_inheritance_GET_string_PK(self): """ Ensure GET on the change_view works on inherited models (returns an Loading Loading @@ -2022,8 +2031,8 @@ class AdminViewStringPrimaryKeyTest(TestCase): self.assertContains(response, should_contain) def test_url_conflicts_with_add(self): "A model with a primary key that ends with add should be visible" add_model = ModelWithStringPrimaryKey(pk="i have something to add") "A model with a primary key that ends with add or is `add` should be visible" add_model = ModelWithStringPrimaryKey.objects.create(pk="i have something to add") add_model.save() response = self.client.get( reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(add_model.pk),)) Loading @@ -2031,6 +2040,11 @@ class AdminViewStringPrimaryKeyTest(TestCase): should_contain = """<h1>Change model with string primary key</h1>""" self.assertContains(response, should_contain) add_model2 = ModelWithStringPrimaryKey.objects.create(pk="add") add_url = reverse('admin:admin_views_modelwithstringprimarykey_add') change_url = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(add_model2.pk),)) self.assertNotEqual(add_url, change_url) def test_url_conflicts_with_delete(self): "A model with a primary key that ends with delete should be visible" delete_model = ModelWithStringPrimaryKey(pk="delete") Loading Loading
django/contrib/admin/options.py +6 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ from django.utils.safestring import mark_safe from django.utils.text import capfirst, get_text_list from django.utils.translation import string_concat, ugettext as _, ungettext from django.views.decorators.csrf import csrf_protect from django.views.generic import RedirectView IS_POPUP_VAR = '_popup' TO_FIELD_VAR = '_to_field' Loading Loading @@ -554,7 +555,11 @@ class ModelAdmin(BaseModelAdmin): url(r'^add/$', wrap(self.add_view), name='%s_%s_add' % info), url(r'^(.+)/history/$', wrap(self.history_view), name='%s_%s_history' % info), url(r'^(.+)/delete/$', wrap(self.delete_view), name='%s_%s_delete' % info), url(r'^(.+)/$', wrap(self.change_view), name='%s_%s_change' % info), url(r'^(.+)/change/$', wrap(self.change_view), name='%s_%s_change' % info), # For backwards compatibility (was the change url before 1.9) url(r'^(.+)/$', wrap(RedirectView.as_view( pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info) ))), ] return urlpatterns Loading
docs/releases/1.9.txt +8 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,14 @@ Minor features * Admin views now have ``model_admin`` or ``admin_site`` attributes. * The URL of the admin change view has been changed (was at ``/admin/<app>/<model>/<pk>/`` by default and is now at ``/admin/<app>/<model>/<pk>/change/``). This should not affect your application unless you have hardcoded admin URLs. In that case, replace those links by :ref:`reversing admin URLs <admin-reverse-urls>` instead. Note that the old URL still redirects to the new one for backwards compatibility, but it may be removed in a future version. :mod:`django.contrib.auth` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading
tests/admin_custom_urls/tests.py +0 −5 Original line number Diff line number Diff line Loading @@ -61,11 +61,6 @@ class AdminCustomUrlsTest(TestCase): """ # Should get the change_view for model instance with PK 'add', not show # the add_view response = self.client.get('/admin/admin_custom_urls/action/add/') self.assertEqual(response.status_code, 200) self.assertContains(response, 'Change action') # Ditto, but use reverse() to build the URL url = reverse('admin:%s_action_change' % Action._meta.app_label, args=(quote('add'),)) response = self.client.get(url) Loading
tests/admin_views/admin.py +1 −1 Original line number Diff line number Diff line Loading @@ -693,7 +693,7 @@ class UnchangeableObjectAdmin(admin.ModelAdmin): def get_urls(self): # Disable change_view, but leave other urls untouched urlpatterns = super(UnchangeableObjectAdmin, self).get_urls() return [p for p in urlpatterns if not p.name.endswith("_change")] return [p for p in urlpatterns if p.name and not p.name.endswith("_change")] def callable_on_unknown(obj): Loading
tests/admin_views/tests.py +16 −2 Original line number Diff line number Diff line Loading @@ -137,6 +137,15 @@ class AdminViewBasicTest(AdminViewBasicTestCase): response = self.client.get(reverse('admin:admin_views_section_change', args=('abc',))) self.assertEqual(response.status_code, 404) def test_basic_edit_GET_old_url_redirect(self): """ The change URL changed in Django 1.9, but the old one still redirects. """ response = self.client.get( reverse('admin:admin_views_section_change', args=(1,)).replace('change/', '') ) self.assertRedirects(response, reverse('admin:admin_views_section_change', args=(1,))) def test_basic_inheritance_GET_string_PK(self): """ Ensure GET on the change_view works on inherited models (returns an Loading Loading @@ -2022,8 +2031,8 @@ class AdminViewStringPrimaryKeyTest(TestCase): self.assertContains(response, should_contain) def test_url_conflicts_with_add(self): "A model with a primary key that ends with add should be visible" add_model = ModelWithStringPrimaryKey(pk="i have something to add") "A model with a primary key that ends with add or is `add` should be visible" add_model = ModelWithStringPrimaryKey.objects.create(pk="i have something to add") add_model.save() response = self.client.get( reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(add_model.pk),)) Loading @@ -2031,6 +2040,11 @@ class AdminViewStringPrimaryKeyTest(TestCase): should_contain = """<h1>Change model with string primary key</h1>""" self.assertContains(response, should_contain) add_model2 = ModelWithStringPrimaryKey.objects.create(pk="add") add_url = reverse('admin:admin_views_modelwithstringprimarykey_add') change_url = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(add_model2.pk),)) self.assertNotEqual(add_url, change_url) def test_url_conflicts_with_delete(self): "A model with a primary key that ends with delete should be visible" delete_model = ModelWithStringPrimaryKey(pk="delete") Loading