Coverage for netbox/api/serializers/generic.py: 54%

31 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1from django.contrib.contenttypes.models import ContentType 

2from drf_spectacular.utils import extend_schema_field 

3from rest_framework import serializers 

4 

5from core.models import ObjectType 

6from netbox.api.fields import ContentTypeField 

7from utilities.api import get_serializer_for_model 

8from utilities.object_types import object_type_identifier 

9 

10__all__ = ( 

11 'GenericObjectSerializer', 

12) 

13 

14 

15class GenericObjectSerializer(serializers.Serializer): 

16 """ 

17 Minimal representation of some generic object identified by ContentType and PK. 

18 """ 

19 object_type = ContentTypeField( 

20 queryset=ContentType.objects.all() 

21 ) 

22 object_id = serializers.IntegerField() 

23 object = serializers.SerializerMethodField(read_only=True) 

24 

25 def __init__(self, *args, **kwargs): 

26 super().__init__(*args, **kwargs) 

27 self._serializer_cache = {} 

28 

29 def to_internal_value(self, data): 

30 data = super().to_internal_value(data) 

31 model = data['object_type'].model_class() 

32 return model.objects.get(pk=data['object_id']) 

33 

34 def to_representation(self, instance): 

35 object_type = ObjectType.objects.get_for_model(instance) 

36 data = { 

37 'object_type': object_type_identifier(object_type), 

38 'object_id': instance.pk, 

39 } 

40 if 'request' in self.context: 

41 data['object'] = self.get_object(instance) 

42 

43 return data 

44 

45 @extend_schema_field(serializers.JSONField(allow_null=True)) 

46 def get_object(self, obj): 

47 if obj.__class__ not in self._serializer_cache: 

48 self._serializer_cache[obj.__class__] = get_serializer_for_model(obj)(nested=True, context=self.context) 

49 serializer = self._serializer_cache[obj.__class__] 

50 return serializer.to_representation(obj)