Skip to content

Commit b976122

Browse files
committed
update segment serializer to handle path file upload. Remove unnecesary SegmentListSerializer and replace it's usage with SegmentSerializer
1 parent 67ca012 commit b976122

File tree

5 files changed

+77
-8
lines changed

5 files changed

+77
-8
lines changed

cesnet_service_path_plugin/api/serializers/segment.py

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
from cesnet_service_path_plugin.models.segment import Segment
1111
from cesnet_service_path_plugin.utils import export_segment_paths_as_geojson
1212

13+
from cesnet_service_path_plugin.utils import process_path_data, determine_file_format_from_extension
14+
from django.core.exceptions import ValidationError as DjangoValidationError
15+
1316

1417
class SegmentSerializer(NetBoxModelSerializer):
15-
"""Default serializer Segment - excludes heavy geometry fields"""
18+
"""Default serializer Segment - now with file upload support"""
1619

1720
url = serializers.HyperlinkedIdentityField(view_name="plugins-api:cesnet_service_path_plugin-api:segment-detail")
1821
provider = ProviderSerializer(required=True, nested=True)
@@ -22,6 +25,13 @@ class SegmentSerializer(NetBoxModelSerializer):
2225
location_b = LocationSerializer(required=True, nested=True)
2326
circuits = CircuitSerializer(required=False, many=True, nested=True)
2427

28+
# Add file upload field
29+
path_file = serializers.FileField(
30+
required=False,
31+
write_only=True, # Only for input, not included in output
32+
help_text="Upload a file containing the path geometry. Supported formats: GeoJSON (.geojson, .json), KML (.kml), KMZ (.kmz)",
33+
)
34+
2535
# Only include lightweight path info
2636
has_path_data = serializers.SerializerMethodField(read_only=True)
2737

@@ -50,6 +60,7 @@ class Meta:
5060
"path_source_format",
5161
"path_notes",
5262
"has_path_data",
63+
"path_file", # Add the file field
5364
"tags",
5465
)
5566
brief_fields = (
@@ -65,6 +76,64 @@ class Meta:
6576
def get_has_path_data(self, obj):
6677
return obj.has_path_data()
6778

79+
def update(self, instance, validated_data):
80+
"""Handle file upload during update"""
81+
path_file = validated_data.pop("path_file", None)
82+
83+
# Update other fields first
84+
instance = super().update(instance, validated_data)
85+
86+
# Process uploaded file if provided
87+
if path_file:
88+
try:
89+
# Process the uploaded file using existing utility functions
90+
file_format = determine_file_format_from_extension(path_file.name)
91+
path_geometry = process_path_data(path_file, file_format)
92+
93+
# Update instance with processed geometry
94+
instance.path_geometry = path_geometry
95+
instance.path_source_format = file_format
96+
# path_length_km will be auto-calculated in the model's save method
97+
instance.save()
98+
99+
except DjangoValidationError as e:
100+
raise serializers.ValidationError(f"Path file error: {str(e)}")
101+
except Exception as e:
102+
raise serializers.ValidationError(f"Error processing file '{path_file.name}': {str(e)}")
103+
104+
return instance
105+
106+
def create(self, validated_data):
107+
"""Handle file upload during creation"""
108+
path_file = validated_data.pop("path_file", None)
109+
110+
# Create instance without path data first
111+
instance = super().create(validated_data)
112+
113+
# Process uploaded file if provided
114+
if path_file:
115+
try:
116+
# Process the uploaded file using existing utility functions
117+
file_format = determine_file_format_from_extension(path_file.name)
118+
path_geometry = process_path_data(path_file, file_format)
119+
120+
# Update instance with processed geometry
121+
instance.path_geometry = path_geometry
122+
instance.path_source_format = file_format
123+
# path_length_km will be auto-calculated in the model's save method
124+
instance.save()
125+
126+
except DjangoValidationError as e:
127+
# Clean up created instance if path processing fails
128+
instance.delete()
129+
raise serializers.ValidationError(f"Path file error: {str(e)}")
130+
except Exception as e:
131+
# Clean up created instance if path processing fails
132+
instance.delete()
133+
raise serializers.ValidationError(f"Error processing file '{path_file.name}': {str(e)}")
134+
135+
return instance
136+
68137

69138
class SegmentListSerializer(NetBoxModelSerializer):
70139
"""Lightweight serializer for list views - excludes heavy geometry fields"""

cesnet_service_path_plugin/api/serializers/segment_circuit_mapping.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from rest_framework import serializers
22
from netbox.api.serializers import NetBoxModelSerializer
3-
from cesnet_service_path_plugin.api.serializers.segment import SegmentListSerializer
4-
from cesnet_service_path_plugin.api.serializers.service_path import ServicePathSerializer
3+
from cesnet_service_path_plugin.api.serializers.segment import SegmentSerializer
54
from cesnet_service_path_plugin.models import SegmentCircuitMapping
65
from circuits.api.serializers import CircuitSerializer
76

@@ -11,7 +10,7 @@ class SegmentCircuitMappingSerializer(NetBoxModelSerializer):
1110
view_name="plugins-api:cesnet_service_path_plugin-api:segmentcircuitmapping-detail"
1211
)
1312
circuit = CircuitSerializer(nested=True)
14-
segment = SegmentListSerializer(nested=True)
13+
segment = SegmentSerializer(nested=True)
1514

1615
class Meta:
1716
model = SegmentCircuitMapping

cesnet_service_path_plugin/api/serializers/service_path.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
from netbox.api.serializers import NetBoxModelSerializer
33
from rest_framework import serializers
44

5-
from cesnet_service_path_plugin.api.serializers.segment import SegmentListSerializer
5+
from cesnet_service_path_plugin.api.serializers.segment import SegmentSerializer
66
from cesnet_service_path_plugin.models import ServicePath
77

88

99
class ServicePathSerializer(NetBoxModelSerializer):
1010
url = serializers.HyperlinkedIdentityField(
1111
view_name="plugins-api:cesnet_service_path_plugin-api:servicepath-detail"
1212
)
13-
segments = SegmentListSerializer(many=True, read_only=True, nested=True)
13+
segments = SegmentSerializer(many=True, read_only=True, nested=True)
1414
circuits = CircuitSerializer(required=False, many=True, nested=True)
1515

1616
class Meta:

cesnet_service_path_plugin/api/serializers/service_path_segment_mapping.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from rest_framework import serializers
22
from netbox.api.serializers import NetBoxModelSerializer
3-
from cesnet_service_path_plugin.api.serializers.segment import SegmentListSerializer
3+
from cesnet_service_path_plugin.api.serializers.segment import SegmentSerializer
44
from cesnet_service_path_plugin.api.serializers.service_path import (
55
ServicePathSerializer,
66
)
@@ -16,7 +16,7 @@ class ServicePathSegmentMappingSerializer(NetBoxModelSerializer):
1616
# required=True
1717
# )
1818
service_path = ServicePathSerializer(nested=True)
19-
segment = SegmentListSerializer(nested=True)
19+
segment = SegmentSerializer(nested=True)
2020

2121
class Meta:
2222
model = ServicePathSegmentMapping

cesnet_service_path_plugin/api/views/segment.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ def get_serializer_class(self):
2020
if pathdata:
2121
return SegmentDetailSerializer
2222

23+
# Use the updated SegmentSerializer for all other actions (including create/update)
2324
return SegmentSerializer

0 commit comments

Comments
 (0)