Coverage for website/thaliawebsite/api/v2/admin/views.py: 93.75%

32 statements  

« prev     ^ index     » next       coverage.py v7.6.7, created at 2025-08-14 10:31 +0000

1from django.contrib.admin.models import ADDITION, CHANGE, DELETION, LogEntry 

2from django.contrib.admin.options import get_content_type_for_model 

3 

4from rest_framework.generics import ( 

5 CreateAPIView, 

6 DestroyAPIView, 

7 ListAPIView, 

8 RetrieveAPIView, 

9 UpdateAPIView, 

10) 

11from rest_framework.permissions import IsAdminUser 

12 

13from thaliawebsite.api.v2.admin.model.diff import ModelDiffCalculator 

14from thaliawebsite.api.v2.admin.permissions import DjangoAdminModelPermissions 

15 

16 

17class AdminPermissionsMixin: 

18 def get_permissions(self): 

19 self.permission_classes.append(IsAdminUser) 

20 self.permission_classes.append(DjangoAdminModelPermissions) 

21 return super().get_permissions() 

22 

23 

24class LogActionMixin: 

25 def log_action(self, request, object, flag=ADDITION, message=None): 

26 """Log that an object has been successfully added. 

27 

28 The default implementation creates an admin LogEntry object. 

29 """ 

30 return LogEntry.objects.log_action( 

31 user_id=request.user.pk, 

32 content_type_id=get_content_type_for_model(object).pk, 

33 object_id=object.pk, 

34 object_repr=str(object), 

35 action_flag=flag, 

36 change_message=message, 

37 ) 

38 

39 

40class AdminListAPIView(AdminPermissionsMixin, ListAPIView): 

41 pass 

42 

43 

44class AdminRetrieveAPIView(AdminPermissionsMixin, RetrieveAPIView): 

45 pass 

46 

47 

48class AdminCreateAPIView(AdminPermissionsMixin, LogActionMixin, CreateAPIView): 

49 def perform_create(self, serializer): 

50 super().perform_create(serializer) 

51 self.log_action( 

52 self.request, 

53 serializer.instance, 

54 ADDITION, 

55 [ 

56 { 

57 "added": { 

58 "name": str(serializer.instance._meta.verbose_name), 

59 "object": str(serializer.instance), 

60 } 

61 } 

62 ], 

63 ) 

64 

65 

66class AdminUpdateAPIView(AdminPermissionsMixin, LogActionMixin, UpdateAPIView): 

67 def perform_update(self, serializer): 

68 helper = ModelDiffCalculator(self.get_object()) 

69 super().perform_update(serializer) 

70 self.log_action( 

71 self.request, 

72 serializer.instance, 

73 CHANGE, 

74 [ 

75 { 

76 "changed": { 

77 "name": str(serializer.instance._meta.verbose_name), 

78 "object": str(serializer.instance), 

79 "fields": helper.set_changed_model( 

80 serializer.instance 

81 ).changed_fields, 

82 } 

83 } 

84 ], 

85 ) 

86 

87 

88class AdminDestroyAPIView(AdminPermissionsMixin, LogActionMixin, DestroyAPIView): 

89 def perform_destroy(self, instance): 

90 log_message = [ 

91 { 

92 "deleted": { 

93 "name": str(instance._meta.verbose_name), 

94 "object": str(instance), 

95 } 

96 } 

97 ] 

98 super().perform_destroy(instance) 

99 self.log_action(self.request, instance, DELETION, log_message)