1

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.

Tamwyn
  • 312
  • 4
  • 16
  • Just to clarify, do you want to include the list of assignments in the custom action response? Or have an example of the response in the API documentation? – Alex M Mar 03 '21 at 12:14
  • In the end both. The serializer is the source for the openapi schema, but I've been struggling with passing my generated data back through the serializer. – Tamwyn Mar 03 '21 at 12:44
  • Thanks for following up. I came across this question looking how to better document responses, and ended up using the [custom schema functional decorator](https://stackoverflow.com/questions/64109297/drf-yasg-how-to-show-sample-response-with-with-api) – Alex M Mar 03 '21 at 13:49

1 Answers1

1

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
)
Tamwyn
  • 312
  • 4
  • 16