drf-spectacular: how to show the primary key in examples section of Swagger

1.5k views Asked by At

I'm trying to show the primary key in the examples section of Swagger, I'm using drf-spectacular and my code looks like:

Serializers.py

class SerializerExample(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ('id','name')

Views.py

class BooksBulkUpdate(APIView):
    @extend_schema(
        request=SerializerExample(many=True),
        responses={200:''},
    )
    def put(self, request, format=None):
        with transaction.atomic():
            for data in request.data:
                book = Book.objects.get(pk=data['id'])
                serializer = SerializerExample(book, data=data, partial=True)
                if serializer.is_valid():
                    serializer.save()
                else:
                    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        return Response()

Only the name field is showing:

enter image description here

The only solution that I found was using an inline serializer which is not the ideal solution because if I update my book serializer I'd have to remember to update also this inline serializer. I wonder if there is a better way of doing this.

1

There are 1 answers

1
rzlvmp On

AFAIK swagger shows input request schema.

For example, you want to add new person and your model is

class Person(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=30)

So you allowed to set only name parameter

Even if you post

{
  "id": "someUUID",
  "name": "NAME",
}

id will be ignored and Django create it automatically by own logic (because it is read only)

But you can set id field writeable:

class SerializerExample(serializers.ModelSerializer):

    id = serializers.UUIDField(write_only=True)
    name = serializers.CharField(write_only=True)

    class Meta:
        model = Person
        fields = ('id','name')

write_only=True means that field will be active when you saving new data and receiving id from request json. In opposite read_only=True will print id field at response (if you trying get data) but ignore it when you saving new data.

So you try to describe API for data adding, and of course that is not allow to set id field in request json.

Not sure if this theory applicable to your case, but hope that will be helpful.