' % reverse('admin:admin_views_answer_change', args=(a2.pk,)),
html=True
)
# A POST request to delete protected objects displays the page which
# says the deletion is prohibited.
response = self.client.post(reverse('admin:admin_views_question_changelist'), delete_confirmation_data)
self.assertContains(response, 'would require deleting the following protected related objects')
self.assertEqual(Question.objects.count(), 2)
def test_model_admin_default_delete_action_no_change_url(self):
"""
The default delete action doesn't break if a ModelAdmin removes the
change_view URL (#20640).
"""
obj = UnchangeableObject.objects.create()
action_data = {
ACTION_CHECKBOX_NAME: obj.pk,
'action': 'delete_selected',
'index': '0',
}
response = self.client.post(reverse('admin:admin_views_unchangeableobject_changelist'), action_data)
# No 500 caused by NoReverseMatch
self.assertEqual(response.status_code, 200)
# The page doesn't display a link to the nonexistent change page.
self.assertContains(response, '
Unchangeable object: %s
' % obj, 1, html=True)
def test_delete_queryset_hook(self):
delete_confirmation_data = {
ACTION_CHECKBOX_NAME: [self.s1.pk, self.s2.pk],
'action': 'delete_selected',
'post': 'yes',
'index': 0,
}
SubscriberAdmin.overridden = False
self.client.post(reverse('admin:admin_views_subscriber_changelist'), delete_confirmation_data)
# SubscriberAdmin.delete_queryset() sets overridden to True.
self.assertIs(SubscriberAdmin.overridden, True)
self.assertEqual(Subscriber.objects.all().count(), 0)
def test_custom_function_mail_action(self):
"""A custom action may be defined in a function."""
action_data = {
ACTION_CHECKBOX_NAME: [self.s1.pk],
'action': 'external_mail',
'index': 0,
}
self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'Greetings from a function action')
def test_custom_function_action_with_redirect(self):
"""Another custom action defined in a function."""
action_data = {
ACTION_CHECKBOX_NAME: [self.s1.pk],
'action': 'redirect_to',
'index': 0,
}
response = self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data)
self.assertEqual(response.status_code, 302)
def test_default_redirect(self):
"""
Actions which don't return an HttpResponse are redirected to the same
page, retaining the querystring (which may contain changelist info).
"""
action_data = {
ACTION_CHECKBOX_NAME: [self.s1.pk],
'action': 'external_mail',
'index': 0,
}
url = reverse('admin:admin_views_externalsubscriber_changelist') + '?o=1'
response = self.client.post(url, action_data)
self.assertRedirects(response, url)
def test_custom_function_action_streaming_response(self):
"""A custom action may return a StreamingHttpResponse."""
action_data = {
ACTION_CHECKBOX_NAME: [self.s1.pk],
'action': 'download',
'index': 0,
}
response = self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data)
content = b''.join(response.streaming_content)
self.assertEqual(content, b'This is the content of the file')
self.assertEqual(response.status_code, 200)
def test_custom_function_action_no_perm_response(self):
"""A custom action may returns an HttpResponse with a 403 code."""
action_data = {
ACTION_CHECKBOX_NAME: [self.s1.pk],
'action': 'no_perm',
'index': 0,
}
response = self.client.post(reverse('admin:admin_views_externalsubscriber_changelist'), action_data)
self.assertEqual(response.status_code, 403)
self.assertEqual(response.content, b'No permission to perform this action')
def test_actions_ordering(self):
"""Actions are ordered as expected."""
response = self.client.get(reverse('admin:admin_views_externalsubscriber_changelist'))
self.assertContains(response, '''