I am trying to build an endpoint using Django Rest Framework for the device detail endpoint on http://127.0.0.1:8000/api/v1/controller/device/<pk>/
Models:-
Device Model
class AbstractDevice(OrgMixin, BaseModel):
name = models.CharField()
mac_address = models.CharField()
key = KeyField()
model = models.CharField()
os = models.CharField()
system = models.CharField()
notes = models.TextField(blank=True, help_text=_('internal notes'))
last_ip = models.GenericIPAddressField()
management_ip = models.GenericIPAddressField()
hardware_id = models.CharField()
Config Model
class AbstractConfig(BaseConfig):
device = models.OneToOneField(Device, on_delete=models.CASCADE)
templates = SortedManyToManyField()
vpn = models.ManyToManyField()
STATUS = Choices('modified', 'applied', 'error')
status = StatusField()
context = JSONField()
For the above models, I have created serializers as:-
DeviceConfigSerializer
class DeviceConfigSerializer(serializers.ModelSerializer):
config = serializers.JSONField()
context = serializers.JSONField()
class Meta:
model = Config
fields = ['backend', 'status', 'templates', 'context', 'config']
DevicedetailSerializer
class DeviceDetailSerializer(serializers.ModelSerializer):
config = DeviceConfigSerializer()
class Meta(BaseMeta):
model = Device
fields = [
'id',
'name',
'organization',
'mac_address',
'key',
'last_ip',
'management_ip',
'model',
'os',
'system',
'notes',
'config',
]
def update(self, instance, validated_data):
instance = self.instance or self.Meta.model(**validated_data)
instance.name = validated_data['name']
instance.organization = validated_data['organization']
instance.mac_address = validated_data['mac_address']
instance.key = validated_data['key']
instance.last_ip = validated_data['last_ip']
instance.management_ip = validated_data['management_ip']
instance.model = validated_data['model']
instance.os = validated_data['os']
instance.system = validated_data['system']
instance.notes = validated_data['notes']
instance.config.backend = validated_data['config']['backend']
instance.config.status = validated_data['config']['status']
config_templates = validated_data['config']['templates']
instance.config.templates.clear()
for template in config_templates:
instance.config.templates.add(template.pk)
instance.config.context = json.loads(
json.dumps(validated_data['config']['context']),
object_pairs_hook=collections.OrderedDict,
)
instance.config.config = json.loads(
json.dumps(validated_data['config']['config']),
object_pairs_hook=collections.OrderedDict,
)
instance.save()
instance.config.save()
return instance
Since I want to incorporate a nested serializer and to make it writable so, it is required to manually add the .update method.
and the views:
Views
class DeviceDetailView(RetrieveUpdateDestroyAPIView):
serializer_class = DeviceDetailSerializer
queryset = Device.objects.all()
The above codes work fine for PUT request but when I try to send a patch request, it expects all the fields, i., until I feed all the fields, I am not able to send the request, but then this is not a patch request when I have to feed all the fields for changing a single field.
ps: I have abstracted the representation of the models for this questions, and tried to give an idea of the model.