Enable modifying individual attributes via REST API

This commit is contained in:
Jeremy Stretch 2025-03-28 10:18:07 -04:00
parent 56d163eed1
commit 4fd3a91d2f
2 changed files with 24 additions and 2 deletions

View File

@ -5,7 +5,7 @@ from rest_framework import serializers
from dcim.choices import *
from dcim.models import DeviceType, ModuleType, ModuleTypeProfile
from netbox.api.fields import ChoiceField, RelatedObjectCountField
from netbox.api.fields import AttributesField, ChoiceField, RelatedObjectCountField
from netbox.api.serializers import NetBoxModelSerializer
from netbox.choices import *
from .manufacturers import ManufacturerSerializer
@ -95,12 +95,17 @@ class ModuleTypeSerializer(NetBoxModelSerializer):
required=False,
allow_null=True
)
attributes = AttributesField(
source='attribute_data',
required=False,
allow_null=True
)
class Meta:
model = ModuleType
fields = [
'id', 'url', 'display_url', 'display', 'profile', 'manufacturer', 'model', 'part_number', 'airflow',
'weight', 'weight_unit', 'description', 'attribute_data', 'comments', 'tags', 'custom_fields', 'created',
'weight', 'weight_unit', 'description', 'attributes', 'comments', 'tags', 'custom_fields', 'created',
'last_updated',
]
brief_fields = ('id', 'url', 'display', 'profile', 'manufacturer', 'model', 'description')

View File

@ -9,6 +9,7 @@ from rest_framework.exceptions import ValidationError
from rest_framework.relations import PrimaryKeyRelatedField, RelatedField
__all__ = (
'AttributesField',
'ChoiceField',
'ContentTypeField',
'IPNetworkSerializer',
@ -172,3 +173,19 @@ class IntegerRangeSerializer(serializers.Serializer):
def to_representation(self, instance):
return instance.lower, instance.upper - 1
class AttributesField(serializers.JSONField):
"""
Custom attributes stored as JSON data.
"""
def to_internal_value(self, data):
data = super().to_internal_value(data)
# If updating an object, start with the initial attribute data. This enables the client to modify
# individual attributes without having to rewrite the entire field.
if data and self.parent.instance:
initial_data = getattr(self.parent.instance, self.source, None) or {}
return {**initial_data, **data}
return data