Coverage for apis_core/history/serializers.py: 48%

71 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-09-03 06:15 +0000

1from drf_spectacular.types import OpenApiTypes 

2from drf_spectacular.utils import extend_schema_field 

3from rest_framework import serializers 

4 

5 

6class ModelChangeSerializer(serializers.Serializer): 

7 field = serializers.CharField() 

8 old = serializers.SerializerMethodField(method_name="get_field_data_old") 

9 new = serializers.SerializerMethodField(method_name="get_field_data_new") 

10 

11 def get_data_for_m2m_field(self, value, field): 

12 sst = [ 

13 str(obj2) 

14 for obj2 in field.related_model.objects.filter( 

15 pk__in=[obj3[field.attname] for obj3 in value] 

16 ) 

17 ] 

18 return " | ".join(sst) 

19 

20 def get_field_data(self, obj, new: bool): 

21 if new: 

22 value = obj.new 

23 else: 

24 value = obj.old 

25 if obj.field in [x.name for x in self._parent_object._meta.local_fields]: 

26 field = self._parent_object._meta.get_field(obj.field) 

27 if field.is_relation and value is not None: 

28 return str(getattr(self._args[1], obj.field)) 

29 return value 

30 else: 

31 for field in self._parent_object._history_m2m_fields: 

32 if field.attname == obj.field: 

33 return self.get_data_for_m2m_field(value, field) 

34 return obj 

35 

36 def get_field_data_new(self, obj): 

37 repr = self.get_field_data(obj, True) 

38 return repr 

39 

40 def get_field_data_old(self, obj): 

41 repr = self.get_field_data(obj, False) 

42 return repr 

43 

44 def __init__(self, instance=None, parent_object=None, **kwargs): 

45 self._parent_object = parent_object 

46 super().__init__(instance, **kwargs) 

47 

48 

49class HistoryLogSerializer(serializers.Serializer): 

50 diff = serializers.SerializerMethodField() 

51 timestamp = serializers.DateTimeField(source="history_date") 

52 user = serializers.CharField(source="history_user") 

53 action = serializers.SerializerMethodField() 

54 model = serializers.CharField(source="instance.__class__.__name__") 

55 module = serializers.CharField(source="instance.__class__._meta.app_label") 

56 instance = serializers.CharField() 

57 object_id = serializers.IntegerField(source="id") 

58 history_id = serializers.IntegerField() 

59 

60 @extend_schema_field(OpenApiTypes.OBJECT) 

61 def get_diff(self, obj): 

62 if obj.history_type == "-": 

63 return None 

64 changed_fields = [] 

65 changes = [] 

66 for change in obj.get_diff(): 

67 changed_fields.append(change.field) 

68 changes.append(ModelChangeSerializer(change, obj).data) 

69 return {"changed_fields": changed_fields, "changes": changes} 

70 

71 def get_action(self, obj) -> str: 

72 match obj.history_type: 

73 case "+": 

74 return "created" 

75 case "~": 

76 return "changed" 

77 case "-": 

78 return "deleted" 

79 

80 

81class HistoryObjectSerializer(serializers.Serializer): 

82 history = serializers.SerializerMethodField() 

83 model = serializers.CharField(source="__class__.__name__") 

84 module = serializers.CharField(source="_meta.app_label") 

85 instance = serializers.SerializerMethodField() 

86 object_id = serializers.IntegerField(source="id") 

87 

88 def get_instance(self, obj) -> str: 

89 return str(obj) 

90 

91 @extend_schema_field(HistoryLogSerializer(many=True)) 

92 def get_history(self, obj): 

93 return HistoryLogSerializer(obj.get_history_data(), many=True).data