Coverage for views/admin_base_view.py: 66%

1 from typing import TYPE_CHECKING, Optional

2

3 from django.contrib import admin

4 from django.contrib.auth.mixins import PermissionRequiredMixin

5 from django.core.exceptions import ImproperlyConfigured

6 from django.utils.decorators import method_decorator

7 from django.views import View

8 from django.views.decorators.cache import never_cache

9

10 if TYPE_CHECKING:

11 from django.contrib.auth.models import AbstractBaseUser

12

13

14@method_decorator(never_cache, name="dispatch")

15 class AdminBaseView(PermissionRequiredMixin, View):

16 """

17 Base class for custom admin views

18 """

19

20 view_name: str = None # Display name for view in admin menu

21 route_name: Optional[

22 str

23 ] = None # The name of the path to be created, defaults to no name

24 route_path: Optional[

25 str

26 ] = None # The slug for the path to be created, defaults to view name

27 permission_required = ()

28 app_label: Optional[str] = None # Must match app label in settings or be None

29

30 def has_permission(self):

31 return self.user_has_permission(self.request.user)

32

33 def user_has_permission(self, user: "AbstractBaseUser") -> bool:

34 """

35 Used to check permission without instance.

36 """

37 if not user.is_active:

38 return False

39

40 if user.is_superuser:

41 return True

42

43 if user.is_staff:

44 if perms := self.get_permission_required():

45 return user.has_perms(perms)

46 return True

47

48 return False

49

50 def get_permission_required(self):

51 if self.permission_required is None:

52 cls_name = self.__class__.__name__

53 message = f"{cls_name} is missing the permission_required attribute. Define {cls_name}.permission_required, or override {cls_name}.get_permission_required()."

54 raise ImproperlyConfigured(message)

55 if isinstance(self.permission_required, str):

56 perms = (self.permission_required,)

57 else:

58 perms = self.permission_required

59 return perms

60

61 def get_context_data(self, *args, **kwargs):

62 """

63 adds admin site context

64 """

65 admin_site = admin.site

66 self.request.name = admin_site.name

67 context: dict = admin_site.each_context(self.request)

68 if hasattr(super(), "get_context_data"):

69 context.update(super().get_context_data(*args, **kwargs))

70 return context