Testing custom admin actions in django
Just pass the parameter action
with the action name.
response = client.post(change_url, {'action': 'mark_as_read', ...})
Checked items are passed as _selected_action
parameter. So code will be like this:
fixtures = [MyModel.objects.create(read=False), MyModel.objects.create(read=True)]should_be_untouched = MyModel.objects.create(read=False)#note the unicode() call belowdata = {'action': 'mark_as_read', '_selected_action': [unicode(f.pk) for f in fixtures]}response = client.post(change_url, data)
This is what I do:
data = {'action': 'mark_as_read', '_selected_action': Node.objects.filter(...).values_list('pk', flat=True)}response = self.client.post(reverse(change_url), data, follow=True)self.assertContains(response, "blah blah...")self.assertEqual(Node.objects.filter(field_to_check=..., pk__in=data['_selected_action']).count(), 0)
A few notes on that, comparing to the accepted answer:
- We can use
values_list
instead of list comprehension to obtain the ids. - We need to specify
follow=True
because it is expected that a successfull post will lead to a redirect - Optionally assert for a successful message
- Check that the changes indeed are reflected on the db.
Here is how you do it with login and everything, a complete test case:
from django.test import TestCasefrom django.urls import reversefrom content_app.models import Contentclass ContentModelAdminTests(TestCase): def setUp(self): # Create some object to perform the action on self.content = Content.objects.create(titles='{"main": "test tile", "seo": "test seo"}') # Create auth user for views using api request factory self.username = 'content_tester' self.password = 'goldenstandard' self.user = User.objects.create_superuser(self.username, 'test@example.com', self.password) def shortDescription(self): return None def test_actions1(self): """ Testing export_as_json action App is content_app, model is content modify as per your app/model """ data = {'action': 'export_as_json', '_selected_action': [self.content._id, ]} change_url = reverse('admin:content_app_content_changelist') self.client.login(username=self.username, password=self.password) response = self.client.post(change_url, data) self.client.logout() self.assertEqual(response.status_code, 200)
Just modify to use your model and custom action and run your test.
UPDATE: If you get a 302, you may need to use follow=True
in self.client.post()
.