DRF Serializer error, "Incorrect type. Expected pk value, received str."

I’ve got a serializer to update a model which has got a field -

used_toys = ListField(child=PrimaryKeyRelatedField(queryset=Toys.objects.all()), required=False)

I am also using OpenAPI for documentation.
The problem is when I add values to that field on Swagger UI and execute, I got this error for array fields.

"used_toys": {
    "0": [
      "Incorrect type. Expected pk value, received str."

Here’s the curl cmd

curl -X PATCH "" -H "accept: application/json" -H "Content-Type: multipart/form-data" -H "X-CSRFToken: k8OYLRtWnUD8CIi6uhLT83xG4HcM52JECc24tT8b19AwzMFFFZZsRK0yz5MBRX46" -d {"used_toys":"\"15\",\"3\""}

I am not sure what is wrong and what I should fix
Any help would be appreciated.

Since you’re supposed to be sending a list of integers, have you tried sending either '{"used_toys": [15, 3]}' or '{"used_toys": ["15", "3"]}'? (enclosing the entire string in single quotes avoids the need of escaping the double-quote characters)

Thanks, @KenWhitesell
Yes, I think so.
But the problem is I am using Swagger and I am not sure how to convert it as you suggested in Swagger.
I think the API would work fine on other client apps because they will make send the data in correct form.

I’m not familiar with swagger, but is it worth confirming that this would work with curl?

A quick glance through the OpenAPI Specification gives me the impression that specifying the field as of type array should produce the desired results. How do you have “used_toys” defined?

This one

used_toys = ListField(child=PrimaryKeyRelatedField(queryset=Toys.objects.all()), required=False)

Would you please send me the link to that OpenAPI Specification?

Yes, I saw how that’s what you have defined in your code - I’m looking for the OpenAPI definition for the field.


Hi, @KenWhitesell

I finally resolved this issue by overriding ModelSerializer’s to_internal_value and update method.
I added my own preprocessing to convert that weird string literal into a valid list.

Thanks for your help

Hii @devspectre could you please share the steps on how you solved the problem?

I am trying to pass a list of student IDs but it is not working.
Below is the to_internal_value method which I have overridden.

def to_internal_value(self, data):
    tempdict = data.copy()
    tempdict['students'] = json.loads(data['students'])
    data = tempdict
    return super(NoticesSerializer, self).to_internal_value(data)

but it always returns the same error

{students: [“Incorrect type. Expected pk value, received list.”]}

It’s saying it received list.

What is your payload look like on client side?

How do you make the requests?
Swagger, Postman or Insomnia?