diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py
index 90394c8f093..2df33c3c86d 100644
--- a/django/contrib/auth/admin.py
+++ b/django/contrib/auth/admin.py
@@ -79,7 +79,7 @@ class UserAdmin(admin.ModelAdmin):
def get_urls(self):
return [
- url(r'^(\d+)/password/$', self.admin_site.admin_view(self.user_change_password)),
+ url(r'^(\d+)/password/$', self.admin_site.admin_view(self.user_change_password), name='auth_user_password_change'),
] + super(UserAdmin, self).get_urls()
def lookup_allowed(self, lookup, value):
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index 5ee5a512dba..7b35c84b45c 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -365,7 +365,7 @@ class ChangeListTests(TestCase):
username='super', email='super@localhost', password='secret')
self.client.login(username='super', password='secret')
event = Event.objects.create(date=datetime.date.today())
- response = self.client.get('/admin/admin_changelist/event/')
+ response = self.client.get(reverse('admin:admin_changelist_event_changelist'))
self.assertContains(response, formats.localize(event.date))
self.assertNotContains(response, six.text_type(event.date))
@@ -678,7 +678,7 @@ class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
"""
self.admin_login(username='super', password='secret')
self.selenium.get('%s%s' % (self.live_server_url,
- '/admin/auth/user/'))
+ reverse('admin:auth_user_changelist')))
form_id = '#changelist-form'
diff --git a/tests/admin_custom_urls/tests.py b/tests/admin_custom_urls/tests.py
index ea3c0704b3c..63cebed7084 100644
--- a/tests/admin_custom_urls/tests.py
+++ b/tests/admin_custom_urls/tests.py
@@ -26,7 +26,9 @@ class AdminCustomUrlsTest(TestCase):
"""
Ensure GET on the add_view works.
"""
- response = self.client.get('/admin/admin_custom_urls/action/!add/')
+ add_url = reverse('admin:admin_custom_urls_action_add')
+ self.assertTrue(add_url.endswith('/!add/'))
+ response = self.client.get(add_url)
self.assertIsInstance(response, TemplateResponse)
self.assertEqual(response.status_code, 200)
@@ -35,7 +37,7 @@ class AdminCustomUrlsTest(TestCase):
Ensure GET on the add_view plus specifying a field value in the query
string works.
"""
- response = self.client.get('/admin/admin_custom_urls/action/!add/', {'name': 'My Action'})
+ response = self.client.get(reverse('admin:admin_custom_urls_action_add'), {'name': 'My Action'})
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'value="My Action"')
@@ -48,7 +50,7 @@ class AdminCustomUrlsTest(TestCase):
"name": 'Action added through a popup',
"description": "Description of added action",
}
- response = self.client.post('/admin/admin_custom_urls/action/!add/', post_data)
+ response = self.client.post(reverse('admin:admin_custom_urls_action_add'), post_data)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'dismissAddRelatedObjectPopup')
self.assertContains(response, 'Action added through a popup')
diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py
index ed931a0cc13..d5c1728bbb2 100644
--- a/tests/admin_inlines/tests.py
+++ b/tests/admin_inlines/tests.py
@@ -2,21 +2,25 @@ from __future__ import unicode_literals
import warnings
-from django.contrib.admin import TabularInline, ModelAdmin
-from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
+from django.contrib.admin import ModelAdmin, TabularInline
from django.contrib.admin.helpers import InlineAdminForm
-from django.contrib.auth.models import User, Permission
+from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
+from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
-from django.test import TestCase, override_settings, RequestFactory
+from django.core.urlresolvers import reverse
+from django.test import RequestFactory, TestCase, override_settings
from django.utils.encoding import force_text
-# local test models
-from .admin import InnerInline, site as admin_site
-from .models import (Holder, Inner, Holder2, Inner2, Holder3, Inner3, Person,
- OutfitItem, Fashionista, Teacher, Parent, Child, Author, Book, Profile,
- ProfileCollection, ParentModelWithCustomPk, ChildModel1, ChildModel2,
- Sighting, Novel, Chapter, FootNote, BinaryTree, SomeParentModel,
- SomeChildModel, Poll, Question, Inner4Stacked, Inner4Tabular, Holder4)
+from .admin import site as admin_site
+from .admin import InnerInline
+from .models import (
+ Author, BinaryTree, Book, Chapter, Child, ChildModel1, ChildModel2,
+ Fashionista, FootNote, Holder, Holder2, Holder3, Holder4, Inner, Inner2,
+ Inner3, Inner4Stacked, Inner4Tabular, Novel, OutfitItem, Parent,
+ ParentModelWithCustomPk, Person, Poll, Profile,
+ ProfileCollection, Question, Sighting, SomeChildModel,
+ SomeParentModel, Teacher,
+)
INLINE_CHANGELINK_HTML = 'class="inlinechangelink">Change'
@@ -30,7 +34,6 @@ class TestInline(TestCase):
holder = Holder(dummy=13)
holder.save()
Inner(dummy=42, holder=holder).save()
- self.change_url = '/admin/admin_inlines/holder/%i/' % holder.id
result = self.client.login(username='super', password='secret')
self.assertEqual(result, True)
@@ -40,7 +43,10 @@ class TestInline(TestCase):
"""
can_delete should be passed to inlineformset factory.
"""
- response = self.client.get(self.change_url)
+ holder = Holder.objects.get(dummy=13)
+ response = self.client.get(
+ reverse('admin:admin_inlines_holder_change', args=(holder.id,))
+ )
inner_formset = response.context['inline_admin_formsets'][0].formset
expected = InnerInline.can_delete
actual = inner_formset.can_delete
@@ -50,13 +56,14 @@ class TestInline(TestCase):
"""Bug #13174."""
holder = Holder.objects.create(dummy=42)
Inner.objects.create(holder=holder, dummy=42, readonly='')
- response = self.client.get('/admin/admin_inlines/holder/%i/'
- % holder.id)
+ response = self.client.get(
+ reverse('admin:admin_inlines_holder_change', args=(holder.id,))
+ )
self.assertContains(response, '')
def test_many_to_many_inlines(self):
"Autogenerated many-to-many inlines are displayed correctly (#13407)"
- response = self.client.get('/admin/admin_inlines/author/add/')
+ response = self.client.get(reverse('admin:admin_inlines_author_add'))
# The heading for the m2m inline block uses the right text
self.assertContains(response, '
Author-book relationships
')
# The "add another" label is correct
@@ -77,7 +84,7 @@ class TestInline(TestCase):
'max_weight': 0,
'shoppingweakness_set-0-item': item.id,
}
- response = self.client.post('/admin/admin_inlines/fashionista/add/', data)
+ response = self.client.post(reverse('admin:admin_inlines_fashionista_add'), data)
self.assertEqual(response.status_code, 302)
self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1)
@@ -94,7 +101,7 @@ class TestInline(TestCase):
'title_set-0-title1': 'a title',
'title_set-0-title2': 'a different title',
}
- response = self.client.post('/admin/admin_inlines/titlecollection/add/', data)
+ response = self.client.post(reverse('admin:admin_inlines_titlecollection_add'), data)
# Here colspan is "4": two fields (title1 and title2), one hidden field and the delete checkbox.
self.assertContains(response, '
The two titles must be the same
')
@@ -102,14 +109,14 @@ class TestInline(TestCase):
"""Admin inline `readonly_field` shouldn't invoke parent ModelAdmin callable"""
# Identically named callable isn't present in the parent ModelAdmin,
# rendering of the add view shouldn't explode
- response = self.client.get('/admin/admin_inlines/novel/add/')
+ response = self.client.get(reverse('admin:admin_inlines_novel_add'))
self.assertEqual(response.status_code, 200)
# View should have the child inlines section
self.assertContains(response, '
')
def test_callable_lookup(self):
"""Admin inline should invoke local callable when its name is listed in readonly_fields"""
- response = self.client.get('/admin/admin_inlines/poll/add/')
+ response = self.client.get(reverse('admin:admin_inlines_poll_add'))
self.assertEqual(response.status_code, 200)
# Add parent object view should have the child inlines section
self.assertContains(response, '
')
@@ -123,11 +130,11 @@ class TestInline(TestCase):
using both the stacked and tabular layouts.
Ref #8190.
"""
- response = self.client.get('/admin/admin_inlines/holder4/add/')
+ response = self.client.get(reverse('admin:admin_inlines_holder4_add'))
self.assertContains(response, '
')
self.assertContains(response,
@@ -551,10 +541,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
def test_change_list_null_boolean_display(self):
Post.objects.create(public=None)
- # This hard-codes the URl because it'll fail if it runs
- # against the 'admin2' custom admin (which doesn't have the
- # Post model).
- response = self.client.get("/test_admin/admin/admin_views/post/")
+ response = self.client.get(reverse('admin:admin_views_post_changelist'))
self.assertContains(response, 'icon-unknown.gif')
def test_i18n_language_non_english_default(self):
@@ -564,7 +551,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
is English. See #13388 and #3594 for more details.
"""
with self.settings(LANGUAGE_CODE='fr'), translation.override('en-us'):
- response = self.client.get('/test_admin/admin/jsi18n/')
+ response = self.client.get(reverse('admin:jsi18n'))
self.assertNotContains(response, 'Choisir une heure')
def test_i18n_language_non_english_fallback(self):
@@ -573,7 +560,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
in cases where the selected language cannot be found.
"""
with self.settings(LANGUAGE_CODE='fr'), translation.override('none'):
- response = self.client.get('/test_admin/admin/jsi18n/')
+ response = self.client.get(reverse('admin:jsi18n'))
self.assertContains(response, 'Choisir une heure')
def test_L10N_deactivated(self):
@@ -582,87 +569,91 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
return localized date/time formats. Refs #14824.
"""
with self.settings(LANGUAGE_CODE='ru', USE_L10N=False), translation.override('none'):
- response = self.client.get('/test_admin/admin/jsi18n/')
+ response = self.client.get(reverse('admin:jsi18n'))
self.assertNotContains(response, '%d.%m.%Y %H:%M:%S')
self.assertContains(response, '%Y-%m-%d %H:%M:%S')
def test_disallowed_filtering(self):
with patch_logger('django.security.DisallowedModelAdminLookup', 'error') as calls:
- response = self.client.get("/test_admin/admin/admin_views/album/?owner__email__startswith=fuzzy")
+ response = self.client.get(
+ "%s?owner__email__startswith=fuzzy" % reverse('admin:admin_views_album_changelist')
+ )
self.assertEqual(response.status_code, 400)
self.assertEqual(len(calls), 1)
# Filters are allowed if explicitly included in list_filter
- response = self.client.get("/test_admin/admin/admin_views/thing/?color__value__startswith=red")
+ response = self.client.get("%s?color__value__startswith=red" % reverse('admin:admin_views_thing_changelist'))
self.assertEqual(response.status_code, 200)
- response = self.client.get("/test_admin/admin/admin_views/thing/?color__value=red")
+ response = self.client.get("%s?color__value=red" % reverse('admin:admin_views_thing_changelist'))
self.assertEqual(response.status_code, 200)
# Filters should be allowed if they involve a local field without the
# need to whitelist them in list_filter or date_hierarchy.
- response = self.client.get("/test_admin/admin/admin_views/person/?age__gt=30")
+ response = self.client.get("%s?age__gt=30" % reverse('admin:admin_views_person_changelist'))
self.assertEqual(response.status_code, 200)
e1 = Employee.objects.create(name='Anonymous', gender=1, age=22, alive=True, code='123')
e2 = Employee.objects.create(name='Visitor', gender=2, age=19, alive=True, code='124')
WorkHour.objects.create(datum=datetime.datetime.now(), employee=e1)
WorkHour.objects.create(datum=datetime.datetime.now(), employee=e2)
- response = self.client.get("/test_admin/admin/admin_views/workhour/")
+ response = self.client.get(reverse('admin:admin_views_workhour_changelist'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'employee__person_ptr__exact')
- response = self.client.get("/test_admin/admin/admin_views/workhour/?employee__person_ptr__exact=%d" % e1.pk)
+ response = self.client.get("%s?employee__person_ptr__exact=%d" % (
+ reverse('admin:admin_views_workhour_changelist'), e1.pk)
+ )
self.assertEqual(response.status_code, 200)
def test_disallowed_to_field(self):
with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls:
- response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'missing_field'})
+ response = self.client.get(reverse('admin:admin_views_section_changelist'), {TO_FIELD_VAR: 'missing_field'})
self.assertEqual(response.status_code, 400)
self.assertEqual(len(calls), 1)
# Specifying a field that is not referred by any other model registered
# to this admin site should raise an exception.
with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls:
- response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'name'})
+ response = self.client.get(reverse('admin:admin_views_section_changelist'), {TO_FIELD_VAR: 'name'})
self.assertEqual(response.status_code, 400)
self.assertEqual(len(calls), 1)
# #23839 - Primary key should always be allowed, even if the referenced model isn't registered.
- response = self.client.get("/test_admin/admin/admin_views/notreferenced/", {TO_FIELD_VAR: 'id'})
+ response = self.client.get(reverse('admin:admin_views_notreferenced_changelist'), {TO_FIELD_VAR: 'id'})
self.assertEqual(response.status_code, 200)
# #23915 - Specifying a field referenced by another model though a m2m should be allowed.
- response = self.client.get("/test_admin/admin/admin_views/recipe/", {TO_FIELD_VAR: 'rname'})
+ response = self.client.get(reverse('admin:admin_views_recipe_changelist'), {TO_FIELD_VAR: 'rname'})
self.assertEqual(response.status_code, 200)
# #23604, #23915 - Specifying a field referenced through a reverse m2m relationship should be allowed.
- response = self.client.get("/test_admin/admin/admin_views/ingredient/", {TO_FIELD_VAR: 'iname'})
+ response = self.client.get(reverse('admin:admin_views_ingredient_changelist'), {TO_FIELD_VAR: 'iname'})
self.assertEqual(response.status_code, 200)
# #23329 - Specifying a field that is not referred by any other model directly registered
# to this admin site but registered through inheritance should be allowed.
- response = self.client.get("/test_admin/admin/admin_views/referencedbyparent/", {TO_FIELD_VAR: 'name'})
+ response = self.client.get(reverse('admin:admin_views_referencedbyparent_changelist'), {TO_FIELD_VAR: 'name'})
self.assertEqual(response.status_code, 200)
# #23431 - Specifying a field that is only referred to by a inline of a registered
# model should be allowed.
- response = self.client.get("/test_admin/admin/admin_views/referencedbyinline/", {TO_FIELD_VAR: 'name'})
+ response = self.client.get(reverse('admin:admin_views_referencedbyinline_changelist'), {TO_FIELD_VAR: 'name'})
self.assertEqual(response.status_code, 200)
# We also want to prevent the add, change, and delete views from
# leaking a disallowed field value.
with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls:
- response = self.client.post("/test_admin/admin/admin_views/section/add/", {TO_FIELD_VAR: 'name'})
+ response = self.client.post(reverse('admin:admin_views_section_add'), {TO_FIELD_VAR: 'name'})
self.assertEqual(response.status_code, 400)
self.assertEqual(len(calls), 1)
section = Section.objects.create()
with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls:
- response = self.client.post("/test_admin/admin/admin_views/section/%d/" % section.pk, {TO_FIELD_VAR: 'name'})
+ response = self.client.post(reverse('admin:admin_views_section_change', args=(section.pk,)), {TO_FIELD_VAR: 'name'})
self.assertEqual(response.status_code, 400)
self.assertEqual(len(calls), 1)
with patch_logger('django.security.DisallowedModelAdminToField', 'error') as calls:
- response = self.client.post("/test_admin/admin/admin_views/section/%d/delete/" % section.pk, {TO_FIELD_VAR: 'name'})
+ response = self.client.post(reverse('admin:admin_views_section_delete', args=(section.pk,)), {TO_FIELD_VAR: 'name'})
self.assertEqual(response.status_code, 400)
self.assertEqual(len(calls), 1)
@@ -673,7 +664,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
can break.
"""
# Filters should be allowed if they are defined on a ForeignKey pointing to this model
- response = self.client.get("/test_admin/admin/admin_views/inquisition/?leader__name=Palin&leader__age=27")
+ response = self.client.get("%s?leader__name=Palin&leader__age=27" % reverse('admin:admin_views_inquisition_changelist'))
self.assertEqual(response.status_code, 200)
def test_popup_dismiss_related(self):
@@ -681,7 +672,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
Regression test for ticket 20664 - ensure the pk is properly quoted.
"""
actor = Actor.objects.create(name="Palin", age=27)
- response = self.client.get("/test_admin/admin/admin_views/actor/?%s" % IS_POPUP_VAR)
+ response = self.client.get("%s?%s" % (reverse('admin:admin_views_actor_changelist'), IS_POPUP_VAR))
self.assertContains(response, "opener.dismissRelatedLookupPopup(window, '%s')" % actor.pk)
def test_hide_change_password(self):
@@ -694,7 +685,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
user.set_unusable_password()
user.save()
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(reverse('admin:index'))
self.assertNotContains(response, reverse('admin:password_change'),
msg_prefix='The "change password" link should not be displayed if a user does not have a usable password.')
@@ -705,8 +696,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
Refs #10057.
"""
instance = UndeletableObject.objects.create(name='foo')
- response = self.client.get('/test_admin/%s/admin_views/undeletableobject/%d/' %
- (self.urlbit, instance.pk))
+ response = self.client.get(reverse('admin:admin_views_undeletableobject_change', args=(instance.pk,)))
self.assertNotContains(response, 'deletelink')
def test_allows_attributeerror_to_bubble_up(self):
@@ -720,7 +710,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
"""
Simple.objects.create()
with self.assertRaises(AttributeError):
- self.client.get('/test_admin/%s/admin_views/simple/' % self.urlbit)
+ self.client.get(reverse('admin:admin_views_simple_changelist'))
def test_changelist_with_no_change_url(self):
"""
@@ -730,7 +720,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
Regression test for #20934
"""
UnchangeableObject.objects.create()
- response = self.client.get('/test_admin/admin/admin_views/unchangeableobject/')
+ response = self.client.get(reverse('admin:admin_views_unchangeableobject_changelist'))
self.assertEqual(response.status_code, 200)
# Check the format of the shown object -- shouldn't contain a change link
self.assertContains(response, '
UnchangeableObject object
', html=True)
@@ -812,7 +802,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
Ensure that the admin/change_form.html template uses block.super in the
bodyclass block.
"""
- response = self.client.get('/test_admin/%s/admin_views/section/add/' % self.urlbit)
+ response = self.client.get(reverse('admin:admin_views_section_add'))
self.assertContains(response, 'bodyclass_consistency_check ')
def test_extended_bodyclass_template_change_password(self):
@@ -821,7 +811,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
super in the bodyclass block.
"""
user = User.objects.get(username='super')
- response = self.client.get('/test_admin/%s/auth/user/%s/password/' % (self.urlbit, user.id))
+ response = self.client.get(reverse('admin:auth_user_password_change', args=(user.id,)))
self.assertContains(response, 'bodyclass_consistency_check ')
def test_extended_bodyclass_template_index(self):
@@ -829,7 +819,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
Ensure that the admin/index.html template uses block.super in the
bodyclass block.
"""
- response = self.client.get('/test_admin/%s/' % self.urlbit)
+ response = self.client.get(reverse('admin:index'))
self.assertContains(response, 'bodyclass_consistency_check ')
def test_extended_bodyclass_change_list(self):
@@ -837,7 +827,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
Ensure that the admin/change_list.html' template uses block.super
in the bodyclass block.
"""
- response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit)
+ response = self.client.get(reverse('admin:admin_views_article_changelist'))
self.assertContains(response, 'bodyclass_consistency_check ')
def test_extended_bodyclass_template_login(self):
@@ -846,7 +836,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
bodyclass block.
"""
self.client.logout()
- response = self.client.get('/test_admin/%s/login/' % self.urlbit)
+ response = self.client.get(reverse('admin:login'))
self.assertContains(response, 'bodyclass_consistency_check ')
def test_extended_bodyclass_template_delete_confirmation(self):
@@ -855,7 +845,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
block.super in the bodyclass block.
"""
group = Group.objects.create(name="foogroup")
- response = self.client.get('/test_admin/%s/auth/group/%s/delete/' % (self.urlbit, group.id))
+ response = self.client.get(reverse('admin:auth_group_delete', args=(group.id,)))
self.assertContains(response, 'bodyclass_consistency_check ')
def test_extended_bodyclass_template_delete_selected_confirmation(self):
@@ -870,7 +860,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
'index': '0',
'_selected_action': group.id
}
- response = self.client.post('/test_admin/%s/auth/group/' % (self.urlbit), post_data)
+ response = self.client.post(reverse('admin:auth_group_changelist'), post_data)
self.assertEqual(response.context['site_header'], 'Django administration')
self.assertContains(response, 'bodyclass_consistency_check ')
@@ -879,7 +869,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
Ensure that one can use a custom template to render an admin filter.
Refs #17515.
"""
- response = self.client.get("/test_admin/admin/admin_views/color2/")
+ response = self.client.get(reverse('admin:admin_views_color2_changelist'))
self.assertTemplateUsed(response, 'custom_filter_template.html')
@@ -887,7 +877,7 @@ class AdminCustomTemplateTests(AdminViewBasicTestCase):
ROOT_URLCONF="admin_views.urls")
class AdminViewFormUrlTest(TestCase):
fixtures = ["admin-views-users.xml"]
- urlbit = "admin3"
+ current_app = "admin3"
def setUp(self):
self.client.login(username='super', password='secret')
@@ -896,7 +886,9 @@ class AdminViewFormUrlTest(TestCase):
"""
Tests whether change_view has form_url in response.context
"""
- response = self.client.get('/test_admin/%s/admin_views/section/1/' % self.urlbit)
+ response = self.client.get(
+ reverse('admin:admin_views_section_change', args=(1,), current_app=self.current_app)
+ )
self.assertIn('form_url', response.context, msg='form_url not present in response.context')
self.assertEqual(response.context['form_url'], 'pony')
@@ -907,7 +899,10 @@ class AdminViewFormUrlTest(TestCase):
Usually, the initial value is set via the GET params.
"""
- response = self.client.get('/test_admin/%s/admin_views/restaurant/add/' % self.urlbit, {'name': 'test_value'})
+ response = self.client.get(
+ reverse('admin:admin_views_restaurant_add', current_app=self.current_app),
+ {'name': 'test_value'}
+ )
# this would be the usual behaviour
self.assertNotContains(response, 'value="test_value"')
# this is the overridden behaviour
@@ -929,8 +924,7 @@ class AdminJavaScriptTest(TestCase):
Refs #17521.
"""
with override_settings(DEBUG=False):
- response = self.client.get(
- '/test_admin/%s/admin_views/section/add/' % 'admin')
+ response = self.client.get(reverse('admin:admin_views_section_add'))
self.assertNotContains(response, 'jquery.js')
self.assertContains(response, 'jquery.min.js')
self.assertNotContains(response, 'prepopulate.js')
@@ -942,8 +936,7 @@ class AdminJavaScriptTest(TestCase):
self.assertNotContains(response, 'inlines.js')
self.assertContains(response, 'inlines.min.js')
with override_settings(DEBUG=True):
- response = self.client.get(
- '/test_admin/%s/admin_views/section/add/' % 'admin')
+ response = self.client.get(reverse('admin:admin_views_section_add'))
self.assertContains(response, 'jquery.js')
self.assertNotContains(response, 'jquery.min.js')
self.assertContains(response, 'prepopulate.js')
@@ -967,7 +960,7 @@ class SaveAsTests(TestCase):
def test_save_as_duplication(self):
"""Ensure save as actually creates a new person"""
post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 1, 'age': 42}
- self.client.post('/test_admin/admin/admin_views/person/1/', post_data)
+ self.client.post(reverse('admin:admin_views_person_change', args=(1,)), post_data)
self.assertEqual(len(Person.objects.filter(name='John M')), 1)
self.assertEqual(len(Person.objects.filter(id=1)), 1)
@@ -977,24 +970,24 @@ class SaveAsTests(TestCase):
invalid data aside save_as_new will not show us a form to overwrite the
initial model.
"""
- response = self.client.get('/test_admin/admin/admin_views/person/1/')
+ change_url = reverse('admin:admin_views_person_change', args=(1,))
+ response = self.client.get(change_url)
self.assertTrue(response.context['save_as'])
post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 3, 'alive': 'checked'}
- response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data)
- self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/')
+ response = self.client.post(change_url, post_data)
+ self.assertEqual(response.context['form_url'], reverse('admin:admin_views_person_add'))
@override_settings(ROOT_URLCONF="admin_views.urls")
class CustomModelAdminTest(AdminViewBasicTestCase):
- urlbit = "admin2"
def test_custom_admin_site_login_form(self):
self.client.logout()
- response = self.client.get('/test_admin/admin2/', follow=True)
+ response = self.client.get(reverse('admin2:index'), follow=True)
self.assertIsInstance(response, TemplateResponse)
self.assertEqual(response.status_code, 200)
- login = self.client.post('/test_admin/admin2/login/', {
- REDIRECT_FIELD_NAME: '/test_admin/admin2/',
+ login = self.client.post(reverse('admin2:login'), {
+ REDIRECT_FIELD_NAME: reverse('admin2:index'),
'username': 'customform',
'password': 'secret',
}, follow=True)
@@ -1004,20 +997,20 @@ class CustomModelAdminTest(AdminViewBasicTestCase):
def test_custom_admin_site_login_template(self):
self.client.logout()
- response = self.client.get('/test_admin/admin2/', follow=True)
+ response = self.client.get(reverse('admin2:index'), follow=True)
self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(response, 'custom_admin/login.html')
self.assertContains(response, 'Hello from a custom login template')
def test_custom_admin_site_logout_template(self):
- response = self.client.get('/test_admin/admin2/logout/')
+ response = self.client.get(reverse('admin2:logout'))
self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(response, 'custom_admin/logout.html')
self.assertContains(response, 'Hello from a custom logout template')
def test_custom_admin_site_index_view_and_template(self):
try:
- response = self.client.get('/test_admin/admin2/')
+ response = self.client.get(reverse('admin2:index'))
except TypeError:
self.fail('AdminSite.index_template should accept a list of template paths')
self.assertIsInstance(response, TemplateResponse)
@@ -1025,39 +1018,41 @@ class CustomModelAdminTest(AdminViewBasicTestCase):
self.assertContains(response, 'Hello from a custom index template *bar*')
def test_custom_admin_site_app_index_view_and_template(self):
- response = self.client.get('/test_admin/admin2/admin_views/')
+ response = self.client.get(reverse('admin2:app_list', args=('admin_views',)))
self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(response, 'custom_admin/app_index.html')
self.assertContains(response, 'Hello from a custom app_index template')
def test_custom_admin_site_password_change_template(self):
- response = self.client.get('/test_admin/admin2/password_change/')
+ response = self.client.get(reverse('admin2:password_change'))
self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(response, 'custom_admin/password_change_form.html')
self.assertContains(response, 'Hello from a custom password change form template')
def test_custom_admin_site_password_change_with_extra_context(self):
- response = self.client.get('/test_admin/admin2/password_change/')
+ response = self.client.get(reverse('admin2:password_change'))
self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(response, 'custom_admin/password_change_form.html')
self.assertContains(response, 'eggs')
def test_custom_admin_site_password_change_done_template(self):
- response = self.client.get('/test_admin/admin2/password_change/done/')
+ response = self.client.get(reverse('admin2:password_change_done'))
self.assertIsInstance(response, TemplateResponse)
self.assertTemplateUsed(response, 'custom_admin/password_change_done.html')
self.assertContains(response, 'Hello from a custom password change done template')
def test_custom_admin_site_view(self):
self.client.login(username='super', password='secret')
- response = self.client.get('/test_admin/%s/my_view/' % self.urlbit)
+ response = self.client.get(reverse('admin2:my_view'))
self.assertEqual(response.content, b"Django is a magical pony!")
def test_pwd_change_custom_template(self):
self.client.login(username='super', password='secret')
su = User.objects.get(username='super')
try:
- response = self.client.get('/test_admin/admin4/auth/user/%s/password/' % su.pk)
+ response = self.client.get(
+ reverse('admin4:auth_user_password_change', args=(su.pk,))
+ )
except TypeError:
self.fail('ModelAdmin.change_user_password_template should accept a list of template paths')
self.assertEqual(response.status_code, 200)
@@ -1106,48 +1101,49 @@ class AdminViewPermissionsTest(TestCase):
get_permission_codename('delete', Section._meta)))
# login POST dicts
+ self.index_url = reverse('admin:index')
self.super_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'username': 'super',
'password': 'secret',
}
self.super_email_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'username': 'super@example.com',
'password': 'secret',
}
self.super_email_bad_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'username': 'super@example.com',
'password': 'notsecret',
}
self.adduser_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'username': 'adduser',
'password': 'secret',
}
self.changeuser_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'username': 'changeuser',
'password': 'secret',
}
self.deleteuser_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'username': 'deleteuser',
'password': 'secret',
}
self.nostaff_login = {
- REDIRECT_FIELD_NAME: '/test_admin/has_permission_admin/',
+ REDIRECT_FIELD_NAME: reverse('has_permission_admin:index'),
'username': 'nostaff',
'password': 'secret',
}
self.joepublic_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'username': 'joepublic',
'password': 'secret',
}
self.no_username_login = {
- REDIRECT_FIELD_NAME: '/test_admin/admin/',
+ REDIRECT_FIELD_NAME: self.index_url,
'password': 'secret',
}
@@ -1159,17 +1155,17 @@ class AdminViewPermissionsTest(TestCase):
Unsuccessful attempts will continue to render the login page with
a 200 status code.
"""
- login_url = reverse('admin:login') + '?next=/test_admin/admin/'
+ login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index'))
# Super User
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
login = self.client.post(login_url, self.super_login)
- self.assertRedirects(login, '/test_admin/admin/')
+ self.assertRedirects(login, self.index_url)
self.assertFalse(login.context)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# Test if user enters email address
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
login = self.client.post(login_url, self.super_email_login)
self.assertContains(login, ERROR_MESSAGE)
@@ -1183,38 +1179,38 @@ class AdminViewPermissionsTest(TestCase):
self.assertContains(login, ERROR_MESSAGE)
# Add User
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
login = self.client.post(login_url, self.adduser_login)
- self.assertRedirects(login, '/test_admin/admin/')
+ self.assertRedirects(login, self.index_url)
self.assertFalse(login.context)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# Change User
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
login = self.client.post(login_url, self.changeuser_login)
- self.assertRedirects(login, '/test_admin/admin/')
+ self.assertRedirects(login, self.index_url)
self.assertFalse(login.context)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# Delete User
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
login = self.client.post(login_url, self.deleteuser_login)
- self.assertRedirects(login, '/test_admin/admin/')
+ self.assertRedirects(login, self.index_url)
self.assertFalse(login.context)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# Regular User should not be able to login.
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
login = self.client.post(login_url, self.joepublic_login)
self.assertEqual(login.status_code, 200)
self.assertContains(login, ERROR_MESSAGE)
# Requests without username should not return 500 errors.
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
login = self.client.post(login_url, self.no_username_login)
self.assertEqual(login.status_code, 200)
@@ -1223,37 +1219,37 @@ class AdminViewPermissionsTest(TestCase):
def test_login_has_permission(self):
# Regular User should not be able to login.
- response = self.client.get('/test_admin/has_permission_admin/')
+ response = self.client.get(reverse('has_permission_admin:index'))
self.assertEqual(response.status_code, 302)
- login = self.client.post('/test_admin/has_permission_admin/login/', self.joepublic_login)
+ login = self.client.post(reverse('has_permission_admin:login'), self.joepublic_login)
self.assertEqual(login.status_code, 200)
self.assertContains(login, 'permission denied')
# User with permissions should be able to login.
- response = self.client.get('/test_admin/has_permission_admin/')
+ response = self.client.get(reverse('has_permission_admin:index'))
self.assertEqual(response.status_code, 302)
- login = self.client.post('/test_admin/has_permission_admin/login/', self.nostaff_login)
- self.assertRedirects(login, '/test_admin/has_permission_admin/')
+ login = self.client.post(reverse('has_permission_admin:login'), self.nostaff_login)
+ self.assertRedirects(login, reverse('has_permission_admin:index'))
self.assertFalse(login.context)
- self.client.get('/test_admin/has_permission_admin/logout/')
+ self.client.get(reverse('has_permission_admin:logout'))
# Staff should be able to login.
- response = self.client.get('/test_admin/has_permission_admin/')
+ response = self.client.get(reverse('has_permission_admin:index'))
self.assertEqual(response.status_code, 302)
- login = self.client.post('/test_admin/has_permission_admin/login/', {
- REDIRECT_FIELD_NAME: '/test_admin/has_permission_admin/',
+ login = self.client.post(reverse('has_permission_admin:login'), {
+ REDIRECT_FIELD_NAME: reverse('has_permission_admin:index'),
'username': 'deleteuser',
'password': 'secret',
})
- self.assertRedirects(login, '/test_admin/has_permission_admin/')
+ self.assertRedirects(login, reverse('has_permission_admin:index'))
self.assertFalse(login.context)
- self.client.get('/test_admin/has_permission_admin/logout/')
+ self.client.get(reverse('has_permission_admin:logout'))
def test_login_successfully_redirects_to_original_URL(self):
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
query_string = 'the-answer=42'
- redirect_url = '/test_admin/admin/?%s' % query_string
+ redirect_url = '%s?%s' % (self.index_url, query_string)
new_next = {REDIRECT_FIELD_NAME: redirect_url}
post_data = self.super_login.copy()
post_data.pop(REDIRECT_FIELD_NAME)
@@ -1264,14 +1260,14 @@ class AdminViewPermissionsTest(TestCase):
def test_double_login_is_not_allowed(self):
"""Regression test for #19327"""
- login_url = reverse('admin:login') + '?next=/test_admin/admin/'
+ login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index'))
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(self.index_url)
self.assertEqual(response.status_code, 302)
# Establish a valid admin session
login = self.client.post(login_url, self.super_login)
- self.assertRedirects(login, '/test_admin/admin/')
+ self.assertRedirects(login, self.index_url)
self.assertFalse(login.context)
# Logging in with non-admin user fails
@@ -1281,67 +1277,67 @@ class AdminViewPermissionsTest(TestCase):
# Establish a valid admin session
login = self.client.post(login_url, self.super_login)
- self.assertRedirects(login, '/test_admin/admin/')
+ self.assertRedirects(login, self.index_url)
self.assertFalse(login.context)
# Logging in with admin user while already logged in
login = self.client.post(login_url, self.super_login)
- self.assertRedirects(login, '/test_admin/admin/')
+ self.assertRedirects(login, self.index_url)
self.assertFalse(login.context)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
def test_add_view(self):
"""Test add view restricts access and actually adds items."""
- login_url = reverse('admin:login') + '?next=/test_admin/admin/'
+ login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index'))
add_dict = {'title': 'Døm ikke',
'content': '
great article
',
'date_0': '2008-03-18', 'date_1': '10:54:39',
'section': 1}
# Change User should not have access to add articles
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.changeuser_login)
# make sure the view removes test cookie
self.assertEqual(self.client.session.test_cookie_worked(), False)
- response = self.client.get('/test_admin/admin/admin_views/article/add/')
+ response = self.client.get(reverse('admin:admin_views_article_add'))
self.assertEqual(response.status_code, 403)
# Try POST just to make sure
- post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
+ post = self.client.post(reverse('admin:admin_views_article_add'), add_dict)
self.assertEqual(post.status_code, 403)
self.assertEqual(Article.objects.all().count(), 3)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# Add user may login and POST to add view, then redirect to admin root
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.adduser_login)
- addpage = self.client.get('/test_admin/admin/admin_views/article/add/')
- change_list_link = '› Articles'
+ addpage = self.client.get(reverse('admin:admin_views_article_add'))
+ change_list_link = '› Articles' % reverse('admin:admin_views_article_changelist')
self.assertNotContains(addpage, change_list_link,
msg_prefix='User restricted to add permission is given link to change list view in breadcrumbs.')
- post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
- self.assertRedirects(post, '/test_admin/admin/')
+ post = self.client.post(reverse('admin:admin_views_article_add'), add_dict)
+ self.assertRedirects(post, self.index_url)
self.assertEqual(Article.objects.all().count(), 4)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'Greetings from a created object')
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# Super can add too, but is redirected to the change list view
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.super_login)
- addpage = self.client.get('/test_admin/admin/admin_views/article/add/')
+ addpage = self.client.get(reverse('admin:admin_views_article_add'))
self.assertContains(addpage, change_list_link,
msg_prefix='Unrestricted user is not given link to change list view in breadcrumbs.')
- post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
- self.assertRedirects(post, '/test_admin/admin/admin_views/article/')
+ post = self.client.post(reverse('admin:admin_views_article_add'), add_dict)
+ self.assertRedirects(post, reverse('admin:admin_views_article_changelist'))
self.assertEqual(Article.objects.all().count(), 5)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# 8509 - if a normal user is already logged in, it is possible
# to change user into the superuser without error
self.client.login(username='joepublic', password='secret')
# Check and make sure that if user expires, data still persists
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.super_login)
# make sure the view removes test cookie
self.assertEqual(self.client.session.test_cookie_worked(), False)
@@ -1349,97 +1345,101 @@ class AdminViewPermissionsTest(TestCase):
def test_change_view(self):
"""Change view should restrict access and allow users to edit items."""
- login_url = reverse('admin:login') + '?next=/test_admin/admin/'
+ login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index'))
change_dict = {'title': 'Ikke fordømt',
'content': '
edited article
',
'date_0': '2008-03-18', 'date_1': '10:54:39',
'section': 1}
+ article_change_url = reverse('admin:admin_views_article_change', args=(1,))
+ article_changelist_url = reverse('admin:admin_views_article_changelist')
# add user should not be able to view the list of article or change any of them
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.adduser_login)
- response = self.client.get('/test_admin/admin/admin_views/article/')
+ response = self.client.get(article_changelist_url)
self.assertEqual(response.status_code, 403)
- response = self.client.get('/test_admin/admin/admin_views/article/1/')
+ response = self.client.get(article_change_url)
self.assertEqual(response.status_code, 403)
- post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict)
+ post = self.client.post(article_change_url, change_dict)
self.assertEqual(post.status_code, 403)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# change user can view all items and edit them
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.changeuser_login)
- response = self.client.get('/test_admin/admin/admin_views/article/')
+ response = self.client.get(article_changelist_url)
self.assertEqual(response.status_code, 200)
- response = self.client.get('/test_admin/admin/admin_views/article/1/')
+ response = self.client.get(article_change_url)
self.assertEqual(response.status_code, 200)
- post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict)
- self.assertRedirects(post, '/test_admin/admin/admin_views/article/')
+ post = self.client.post(article_change_url, change_dict)
+ self.assertRedirects(post, article_changelist_url)
self.assertEqual(Article.objects.get(pk=1).content, '
edited article
')
# one error in form should produce singular error message, multiple errors plural
change_dict['title'] = ''
- post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict)
+ post = self.client.post(article_change_url, change_dict)
self.assertContains(post, 'Please correct the error below.',
msg_prefix='Singular error message not found in response to post with one error')
change_dict['content'] = ''
- post = self.client.post('/test_admin/admin/admin_views/article/1/', change_dict)
+ post = self.client.post(article_change_url, change_dict)
self.assertContains(post, 'Please correct the errors below.',
msg_prefix='Plural error message not found in response to post with multiple errors')
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# Test redirection when using row-level change permissions. Refs #11513.
- RowLevelChangePermissionModel.objects.create(id=1, name="odd id")
- RowLevelChangePermissionModel.objects.create(id=2, name="even id")
+ r1 = RowLevelChangePermissionModel.objects.create(id=1, name="odd id")
+ r2 = RowLevelChangePermissionModel.objects.create(id=2, name="even id")
+ change_url_1 = reverse('admin:admin_views_rowlevelchangepermissionmodel_change', args=(r1.pk,))
+ change_url_2 = reverse('admin:admin_views_rowlevelchangepermissionmodel_change', args=(r2.pk,))
for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]:
self.client.post(login_url, login_dict)
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/')
+ response = self.client.get(change_url_1)
self.assertEqual(response.status_code, 403)
- response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'})
+ response = self.client.post(change_url_1, {'name': 'changed'})
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
self.assertEqual(response.status_code, 403)
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/')
+ response = self.client.get(change_url_2)
self.assertEqual(response.status_code, 200)
- response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed'})
+ response = self.client.post(change_url_2, {'name': 'changed'})
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
- self.assertRedirects(response, '/test_admin/admin/')
- self.client.get('/test_admin/admin/logout/')
+ self.assertRedirects(response, self.index_url)
+ self.client.get(reverse('admin:logout'))
for login_dict in [self.joepublic_login, self.no_username_login]:
self.client.post(login_url, login_dict)
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', follow=True)
+ response = self.client.get(change_url_1, follow=True)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'login-form')
- response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/', {'name': 'changed'}, follow=True)
+ response = self.client.post(change_url_1, {'name': 'changed'}, follow=True)
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=1).name, 'odd id')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'login-form')
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', follow=True)
+ response = self.client.get(change_url_2, follow=True)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'login-form')
- response = self.client.post('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/', {'name': 'changed again'}, follow=True)
+ response = self.client.post(change_url_2, {'name': 'changed again'}, follow=True)
self.assertEqual(RowLevelChangePermissionModel.objects.get(id=2).name, 'changed')
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'login-form')
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
def test_history_view(self):
"""History view should restrict access."""
- login_url = reverse('admin:login') + '?next=/test_admin/admin/'
+ login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index'))
# add user should not be able to view the list of article or change any of them
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.adduser_login)
- response = self.client.get('/test_admin/admin/admin_views/article/1/history/')
+ response = self.client.get(reverse('admin:admin_views_article_history', args=(1,)))
self.assertEqual(response.status_code, 403)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
# change user can view all items and edit them
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.changeuser_login)
- response = self.client.get('/test_admin/admin/admin_views/article/1/history/')
+ response = self.client.get(reverse('admin:admin_views_article_history', args=(1,)))
self.assertEqual(response.status_code, 200)
# Test redirection when using row-level change permissions. Refs #11513.
@@ -1447,33 +1447,37 @@ class AdminViewPermissionsTest(TestCase):
RowLevelChangePermissionModel.objects.create(id=2, name="even id")
for login_dict in [self.super_login, self.changeuser_login, self.adduser_login, self.deleteuser_login]:
self.client.post(login_url, login_dict)
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/history/')
+ response = self.client.get(reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(1,)))
self.assertEqual(response.status_code, 403)
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/history/')
+ response = self.client.get(reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(2,)))
self.assertEqual(response.status_code, 200)
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
for login_dict in [self.joepublic_login, self.no_username_login]:
self.client.post(login_url, login_dict)
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/1/history/', follow=True)
+ response = self.client.get(
+ reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(1,)), follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'login-form')
- response = self.client.get('/test_admin/admin/admin_views/rowlevelchangepermissionmodel/2/history/', follow=True)
+ response = self.client.get(
+ reverse('admin:admin_views_rowlevelchangepermissionmodel_history', args=(2,)), follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'login-form')
- self.client.get('/test_admin/admin/logout/')
+ self.client.get(reverse('admin:logout'))
def test_conditionally_show_add_section_link(self):
"""
The foreign key widget should only show the "add related" button if the
user has permission to add that related item.
"""
- login_url = reverse('admin:login') + '?next=/test_admin/admin/'
+ login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index'))
# Set up and log in user.
- url = '/test_admin/admin/admin_views/article/add/'
+ url = reverse('admin:admin_views_article_add')
add_link_text = 'add_id_section'
self.client.post(login_url, self.adduser_login)
# The user can't add sections yet, so they shouldn't see the "add
@@ -1498,7 +1502,7 @@ class AdminViewPermissionsTest(TestCase):
login_url = reverse('admin:login')
# Set up and log in user.
- url = '/test_admin/admin/admin_views/article/add/'
+ url = reverse('admin:admin_views_article_add')
change_link_text = 'change_id_section'
self.client.post(login_url, self.adduser_login)
# The user can't change sections yet, so they shouldn't see the "change
@@ -1525,9 +1529,9 @@ class AdminViewPermissionsTest(TestCase):
login_url = reverse('admin:login')
# Set up and log in user.
- url = '/test_admin/admin/admin_views/article/add/'
+ url = reverse('admin:admin_views_article_add')
delete_link_text = 'delete_id_sub_section'
- self.client.get('/test_admin/admin/')
+ self.client.get(self.index_url)
self.client.post(login_url, self.adduser_login)
# The user can't delete sections yet, so they shouldn't see the "delete
# section" link.
@@ -1544,85 +1548,86 @@ class AdminViewPermissionsTest(TestCase):
self.assertContains(response, delete_link_text)
def test_custom_model_admin_templates(self):
- login_url = reverse('admin:login') + '?next=/test_admin/admin/'
- self.client.get('/test_admin/admin/')
+ login_url = '%s?next=%s' % (reverse('admin:login'), reverse('admin:index'))
+ self.client.get(self.index_url)
self.client.post(login_url, self.super_login)
# Test custom change list template with custom extra context
- response = self.client.get('/test_admin/admin/admin_views/customarticle/')
+ response = self.client.get(reverse('admin:admin_views_customarticle_changelist'))
self.assertContains(response, "var hello = 'Hello!';")
self.assertTemplateUsed(response, 'custom_admin/change_list.html')
# Test custom add form template
- response = self.client.get('/test_admin/admin/admin_views/customarticle/add/')
+ response = self.client.get(reverse('admin:admin_views_customarticle_add'))
self.assertTemplateUsed(response, 'custom_admin/add_form.html')
# Add an article so we can test delete, change, and history views
- post = self.client.post('/test_admin/admin/admin_views/customarticle/add/', {
+ post = self.client.post(reverse('admin:admin_views_customarticle_add'), {
'content': '
' % (change_url, escape(self.pk))
self.assertContains(response, should_contain)
def test_recentactions_link(self):
"The link from the recent actions list referring to the changeform of the object should be quoted"
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(reverse('admin:index'))
link = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(self.pk),))
should_contain = """%s""" % (escape(link), escape(self.pk))
self.assertContains(response, should_contain)
def test_recentactions_without_content_type(self):
"If a LogEntry is missing content_type it will not display it in span tag under the hyperlink."
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(reverse('admin:index'))
link = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(self.pk),))
should_contain = """%s""" % (escape(link), escape(self.pk))
self.assertContains(response, should_contain)
@@ -1982,7 +2009,7 @@ class AdminViewStringPrimaryKeyTest(TestCase):
logentry.save()
counted_presence_before = response.content.count(force_bytes(should_contain))
- response = self.client.get('/test_admin/admin/')
+ response = self.client.get(reverse('admin:index'))
counted_presence_after = response.content.count(force_bytes(should_contain))
self.assertEqual(counted_presence_before - 1,
counted_presence_after)
@@ -1991,25 +2018,31 @@ class AdminViewStringPrimaryKeyTest(TestCase):
"LogEntry.get_admin_url returns a URL to edit the entry's object or None for non-existent (possibly deleted) models"
log_entry_model = "modelwithstringprimarykey" # capitalized in Recent Actions
logentry = LogEntry.objects.get(content_type__model__iexact=log_entry_model)
- model = "modelwithstringprimarykey"
- desired_admin_url = "/test_admin/admin/admin_views/%s/%s/" % (model, iri_to_uri(quote(self.pk)))
+ desired_admin_url = reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(self.pk),))
+
self.assertEqual(logentry.get_admin_url(), desired_admin_url)
+ self.assertIn(iri_to_uri(quote(self.pk)), logentry.get_admin_url())
logentry.content_type.model = "non-existent"
self.assertEqual(logentry.get_admin_url(), None)
def test_deleteconfirmation_link(self):
"The link from the delete confirmation page referring back to the changeform of the object should be quoted"
- response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/delete/' % quote(self.pk))
+ response = self.client.get(reverse('admin:admin_views_modelwithstringprimarykey_delete', args=(quote(self.pk),)))
# this URL now comes through reverse(), thus url quoting and iri_to_uri encoding
- should_contain = """/%s/">%s""" % (escape(iri_to_uri(quote(self.pk))), escape(self.pk))
+ change_url = reverse(
+ 'admin:admin_views_modelwithstringprimarykey_change', args=('__fk__',)
+ ).replace('__fk__', escape(iri_to_uri(quote(self.pk))))
+ should_contain = '%s' % (change_url, escape(self.pk))
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")
add_model.save()
- response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(add_model.pk))
+ response = self.client.get(
+ reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(add_model.pk),))
+ )
should_contain = """
Change model with string primary key
"""
self.assertContains(response, should_contain)
@@ -2017,7 +2050,9 @@ class AdminViewStringPrimaryKeyTest(TestCase):
"A model with a primary key that ends with delete should be visible"
delete_model = ModelWithStringPrimaryKey(pk="delete")
delete_model.save()
- response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(delete_model.pk))
+ response = self.client.get(
+ reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(delete_model.pk),))
+ )
should_contain = """
Change model with string primary key
"""
self.assertContains(response, should_contain)
@@ -2025,7 +2060,9 @@ class AdminViewStringPrimaryKeyTest(TestCase):
"A model with a primary key that ends with history should be visible"
history_model = ModelWithStringPrimaryKey(pk="history")
history_model.save()
- response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/%s/' % quote(history_model.pk))
+ response = self.client.get(
+ reverse('admin:admin_views_modelwithstringprimarykey_change', args=(quote(history_model.pk),))
+ )
should_contain = """