I have a custom action which gets an input and should return a list of assigned cidr objects.
@action(detail=True, methods=['POST'], name="Assign Subnet from Pool", serializer_class=AssignmentSerializer)
def assign(self, request, pk=None):
"""Adds a new address within the pool
"""
pool = self.get_object()
serializer = AssignmentSerializer(data=request.data)
if not serializer.is_valid():
return Response(status=status.HTTP_412_PRECONDITION_FAILED)
# Computation generating a dictionary with cidr objects (result)
# Successfully assigned
serializer.save(assignments=[cidr for cidr in result.values()])
return Response(serializer.data, status=status.HTTP_201_CREATED)
My serializer looks like this
class AssignmentSerializer(serializers.Serializer):
"""This is a serializer for a custom form
"""
hostname = serializers.CharField(required=False)
useDefaultDomain = serializers.BooleanField(default=True, help_text='Use pools default domain')
description = serializers.CharField(required=True)
assignments = CIDRSerializer(many=True, required=False, help_text='Will not be evaluated on request but contain the assignments in the response')
However, I haven't figured out how to include the assignments in the response. There is no need for the serializer to persist them into the database, it is just necessary to use the serializer for automated openapi schema generation.
The trick here are read_only/write_only attributes.
The serializer has to look like this:
class AssignmentSerializer(serializers.Serializer):
hostname = serializers.CharField(required=False, write_only=True)
useDefaultDomain = serializers.BooleanField(default=True, write_only=True, help_text='Use pools default domain')
description = serializers.CharField(required=True, write_only=True)
assignments = CIDRSerializer(many=True, read_only=True)
And then it can be returned like this:
return Response(
AssignmentSerializer(
instance={
'assignments': list(result.values())
},
read_only=True,
context={'request': request}
).data,
status=status.HTTP_201_CREATED
)