2018-06-19 03:07:29 +08:00
|
|
|
from django.contrib import admin
|
|
|
|
from django.contrib.auth.models import Permission, User
|
|
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
from django.test import TestCase
|
|
|
|
|
|
|
|
from .models import Band
|
|
|
|
|
|
|
|
|
|
|
|
class AdminActionsTests(TestCase):
|
|
|
|
@classmethod
|
|
|
|
def setUpTestData(cls):
|
|
|
|
cls.superuser = User.objects.create_superuser(
|
|
|
|
username="super", password="secret", email="super@example.com"
|
|
|
|
)
|
|
|
|
content_type = ContentType.objects.get_for_model(Band)
|
|
|
|
Permission.objects.create(
|
|
|
|
name="custom", codename="custom_band", content_type=content_type
|
|
|
|
)
|
|
|
|
for user_type in ("view", "add", "change", "delete", "custom"):
|
|
|
|
username = "%suser" % user_type
|
|
|
|
user = User.objects.create_user(
|
|
|
|
username=username, password="secret", is_staff=True
|
|
|
|
)
|
|
|
|
permission = Permission.objects.get(
|
|
|
|
codename="%s_band" % user_type, content_type=content_type
|
|
|
|
)
|
|
|
|
user.user_permissions.add(permission)
|
|
|
|
setattr(cls, username, user)
|
|
|
|
|
|
|
|
def test_get_actions_respects_permissions(self):
|
|
|
|
class MockRequest:
|
|
|
|
pass
|
|
|
|
|
|
|
|
class BandAdmin(admin.ModelAdmin):
|
|
|
|
actions = ["custom_action"]
|
|
|
|
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action
|
2018-06-19 03:07:29 +08:00
|
|
|
def custom_action(modeladmin, request, queryset):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def has_custom_permission(self, request):
|
|
|
|
return request.user.has_perm("%s.custom_band" % self.opts.app_label)
|
|
|
|
|
|
|
|
ma = BandAdmin(Band, admin.AdminSite())
|
|
|
|
mock_request = MockRequest()
|
|
|
|
mock_request.GET = {}
|
|
|
|
cases = [
|
|
|
|
(None, self.viewuser, ["custom_action"]),
|
|
|
|
("view", self.superuser, ["delete_selected", "custom_action"]),
|
|
|
|
("view", self.viewuser, ["custom_action"]),
|
|
|
|
("add", self.adduser, ["custom_action"]),
|
|
|
|
("change", self.changeuser, ["custom_action"]),
|
|
|
|
("delete", self.deleteuser, ["delete_selected", "custom_action"]),
|
|
|
|
("custom", self.customuser, ["custom_action"]),
|
|
|
|
]
|
|
|
|
for permission, user, expected in cases:
|
|
|
|
with self.subTest(permission=permission, user=user):
|
|
|
|
if permission is None:
|
|
|
|
if hasattr(BandAdmin.custom_action, "allowed_permissions"):
|
|
|
|
del BandAdmin.custom_action.allowed_permissions
|
|
|
|
else:
|
|
|
|
BandAdmin.custom_action.allowed_permissions = (permission,)
|
|
|
|
mock_request.user = user
|
|
|
|
actions = ma.get_actions(mock_request)
|
|
|
|
self.assertEqual(list(actions.keys()), expected)
|
2018-11-10 07:52:30 +08:00
|
|
|
|
|
|
|
def test_actions_inheritance(self):
|
|
|
|
class AdminBase(admin.ModelAdmin):
|
|
|
|
actions = ["custom_action"]
|
|
|
|
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action
|
2018-11-10 07:52:30 +08:00
|
|
|
def custom_action(modeladmin, request, queryset):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class AdminA(AdminBase):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class AdminB(AdminBase):
|
|
|
|
actions = None
|
|
|
|
|
|
|
|
ma1 = AdminA(Band, admin.AdminSite())
|
|
|
|
action_names = [name for _, name, _ in ma1._get_base_actions()]
|
|
|
|
self.assertEqual(action_names, ["delete_selected", "custom_action"])
|
|
|
|
# `actions = None` removes actions from superclasses.
|
|
|
|
ma2 = AdminB(Band, admin.AdminSite())
|
|
|
|
action_names = [name for _, name, _ in ma2._get_base_actions()]
|
|
|
|
self.assertEqual(action_names, ["delete_selected"])
|
2020-03-20 15:24:14 +08:00
|
|
|
|
2020-11-14 04:41:18 +08:00
|
|
|
def test_global_actions_description(self):
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action(description="Site-wide admin action 1.")
|
2020-11-14 04:41:18 +08:00
|
|
|
def global_action_1(modeladmin, request, queryset):
|
|
|
|
pass
|
|
|
|
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action
|
2020-11-14 04:41:18 +08:00
|
|
|
def global_action_2(modeladmin, request, queryset):
|
|
|
|
pass
|
|
|
|
|
|
|
|
admin_site = admin.AdminSite()
|
|
|
|
admin_site.add_action(global_action_1)
|
|
|
|
admin_site.add_action(global_action_2)
|
|
|
|
|
|
|
|
class BandAdmin(admin.ModelAdmin):
|
|
|
|
pass
|
|
|
|
|
|
|
|
ma = BandAdmin(Band, admin_site)
|
|
|
|
self.assertEqual(
|
|
|
|
[description for _, _, description in ma._get_base_actions()],
|
|
|
|
[
|
|
|
|
"Delete selected %(verbose_name_plural)s",
|
|
|
|
"Site-wide admin action 1.",
|
|
|
|
"Global action 2",
|
|
|
|
],
|
|
|
|
)
|
|
|
|
|
2020-03-20 15:24:14 +08:00
|
|
|
def test_actions_replace_global_action(self):
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action(description="Site-wide admin action 1.")
|
2020-03-20 15:24:14 +08:00
|
|
|
def global_action_1(modeladmin, request, queryset):
|
|
|
|
pass
|
|
|
|
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action(description="Site-wide admin action 2.")
|
2020-03-20 15:24:14 +08:00
|
|
|
def global_action_2(modeladmin, request, queryset):
|
|
|
|
pass
|
|
|
|
|
|
|
|
admin.site.add_action(global_action_1, name="custom_action_1")
|
|
|
|
admin.site.add_action(global_action_2, name="custom_action_2")
|
|
|
|
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action(description="Local admin action 1.")
|
2020-03-20 15:24:14 +08:00
|
|
|
def custom_action_1(modeladmin, request, queryset):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class BandAdmin(admin.ModelAdmin):
|
|
|
|
actions = [custom_action_1, "custom_action_2"]
|
|
|
|
|
2021-01-14 00:19:22 +08:00
|
|
|
@admin.action(description="Local admin action 2.")
|
2020-03-20 15:24:14 +08:00
|
|
|
def custom_action_2(self, request, queryset):
|
|
|
|
pass
|
|
|
|
|
|
|
|
ma = BandAdmin(Band, admin.site)
|
|
|
|
self.assertEqual(ma.check(), [])
|
|
|
|
self.assertEqual(
|
|
|
|
[
|
|
|
|
desc
|
|
|
|
for _, name, desc in ma._get_base_actions()
|
|
|
|
if name.startswith("custom_action")
|
|
|
|
],
|
|
|
|
[
|
|
|
|
"Local admin action 1.",
|
|
|
|
"Local admin action 2.",
|
|
|
|
],
|
|
|
|
)
|