Skip to content

Commit

Permalink
SCKAN-323 refactor: Move custom update logic from view to serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
afonsobspinto committed Nov 14, 2024
1 parent f19f66d commit d2410ab
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 61 deletions.
36 changes: 35 additions & 1 deletion backend/composer/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.contrib.auth.models import User
from django.db.models import Q
from django.forms import ValidationError
from django_fsm import FSMField
from drf_writable_nested.mixins import UniqueFieldsMixin
from drf_writable_nested.serializers import WritableNestedModelSerializer
Expand Down Expand Up @@ -703,8 +704,41 @@ class Meta:
"has_notes",
"statement_preview",
"errors",
"graph_rendering_state"
"graph_rendering_state",
)
read_only_fields = ("owner", "owner_id")

def update(self, instance, validated_data):
validated_data.pop("owner", None)
validated_data.pop("owner_id", None)

graph_rendering_state_data = validated_data.pop("graph_rendering_state", None)
if graph_rendering_state_data is not None:
graph_state, _ = GraphRenderingState.objects.get_or_create(
connectivity_statement=instance, defaults={"serialized_graph": {}}
)

# Update the serialized_graph with incoming data
graph_state.serialized_graph = graph_rendering_state_data.get(
"serialized_graph", graph_state.serialized_graph
)
graph_state.saved_by = self.context["request"].user
graph_state.save()

# Handle origins
origins = validated_data.pop("origins", None)
if origins is not None:
instance.origins.set(origins)

# Proceed with the standard update
return super().update(instance, validated_data)

def to_representation(self, instance):
"""
After updating, use the main serializer to represent the instance,
ensuring that 'origins' are serialized as full objects.
"""
return ConnectivityStatementSerializer(instance, context=self.context).data


class KnowledgeStatementSerializer(ConnectivityStatementSerializer):
Expand Down
72 changes: 12 additions & 60 deletions backend/composer/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ class ConnectivityStatementViewSet(
service = ConnectivityStatementStateService

def get_serializer_class(self):
if self.action in ['update', 'partial_update']:
return ConnectivityStatementUpdateSerializer
if self.action == "list":
return BaseConnectivityStatementSerializer
return ConnectivityStatementSerializer
Expand All @@ -357,81 +359,31 @@ def get_queryset(self):
return ConnectivityStatement.objects.excluding_draft()
return super().get_queryset()

def handle_graph_rendering_state(self, instance, graph_rendering_state_data, user):
if graph_rendering_state_data:
if (
hasattr(instance, "graph_rendering_state")
and instance.graph_rendering_state is not None
):
# Update the existing graph state
instance.graph_rendering_state.serialized_graph = (
graph_rendering_state_data.get(
"serialized_graph",
instance.graph_rendering_state.serialized_graph,
)
)
instance.graph_rendering_state.saved_by = user
instance.graph_rendering_state.save()
else:
# Create a new graph state if none exists
GraphRenderingState.objects.create(
connectivity_statement=instance,
serialized_graph=graph_rendering_state_data.get(
"serialized_graph", {}
),
saved_by=user,
)
"""
Override the update method to apply the extend_schema decorator.
The actual update logic is handled by the serializer.
"""

@extend_schema(
methods=["PUT"],
request=ConnectivityStatementUpdateSerializer,
responses={200: ConnectivityStatementSerializer},
)
def update(self, request, *args, **kwargs):
origin_ids = request.data.pop("origins", None)
graph_rendering_state_data = request.data.pop("graph_rendering_state", None)

response = super().update(request, *args, **kwargs)

if response.status_code == status.HTTP_200_OK:
instance = self.get_object()
return super().update(request, *args, **kwargs)

# Handle custom updates
self.handle_graph_rendering_state(
instance, graph_rendering_state_data, request.user
)
if origin_ids is not None:
instance.set_origins(origin_ids)

# Re-serialize the instance with all modifications
serializer = self.get_serializer(instance)
return Response(serializer.data, status=status.HTTP_200_OK)

return response
"""
Override the partial_update method to apply the extend_schema decorator.
The actual update logic is handled by the serializer.
"""

@extend_schema(
methods=["PATCH"],
request=ConnectivityStatementUpdateSerializer,
responses={200: ConnectivityStatementSerializer},
)
def partial_update(self, request, *args, **kwargs):
graph_rendering_state_data = request.data.pop("graph_rendering_state", None)

response = super().partial_update(request, *args, **kwargs)

if response.status_code == status.HTTP_200_OK:
instance = self.get_object()

# Handle custom updates
self.handle_graph_rendering_state(
instance, graph_rendering_state_data, request.user
)

# Re-serialize the instance with all modifications
serializer = self.get_serializer(instance)
return Response(serializer.data, status=status.HTTP_200_OK)

return response
return super().partial_update(request, *args, **kwargs)


@extend_schema(tags=["public"])
Expand Down
1 change: 1 addition & 0 deletions frontend/src/apiclient/backend/.openapi-generator/FILES
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.gitignore
.npmignore
.openapi-generator-ignore
api.ts
base.ts
common.ts
Expand Down

0 comments on commit d2410ab

Please sign in to comment.