django - "Incorrect type. Expected pk value, received str" error

37.6k views Asked by At

I my django-rest-framework I have the following models:

Basically every ride has one final destination and can have multiple middle destinations.

models.py:

class Destination(models.Model):
    name=models.CharField(max_length=30)

class Ride(models.Model):
    driver = models.ForeignKey('auth.User', related_name='rides_as_driver')
    destination=models.ForeignKey(Destination, related_name='rides_as_final_destination')
    leaving_time=models.TimeField()
    num_of_spots=models.IntegerField()
    passengers=models.ManyToManyField('auth.User', related_name="rides_as_passenger")
    mid_destinations=models.ManyToManyField(Destination, related_name='rides_as_middle_destination')

serializers.py - RideSerializer

class RideSerializer(serializers.ModelSerializer):
    driver = serializers.ReadOnlyField(source='driver.user.username')

    class Meta:
        model = Ride
        fields = ('driver', 'destination', 'leaving_time',
                  'num_of_spots', 'passengers', 'mid_destinations')
        read_only_fields = ('driver', 'passengers', 'mid_destinations')

Problem is - When I am trying to POST to /rides/ in order to add a ride - for example {destination=LA, leaving_time=19:45, num_of_spots=4}

I get error "destination":["Incorrect type. Expected pk value, received str."]}

couple of questions:

  • What is this error? if I have a destination as a foreign key in the Ride model, does it mean that the destination that I am adding has to be already in the Destinations table?

  • How to fix this error?

3

There are 3 answers

5
Kevin Brown-Silva On BEST ANSWER

The issue is that you are passing the name of the related Destination object into the serializer, instead of passing the pk/id of the Destination object. So Django REST framework is seeing this and complaining, because it can't resolve LA into an object.

It sounds like you may actually be looking for a SlugRelatedField, which allows you to identify objects by a slug (LA in this case) instead of their primary keys.

0
7guyo On

Angular/Django Rest Framework

I had similar problem when trying to post a formdata that has a field with some array values. It turned out that I was using a wrong content-type in the post headers of angular frontend. All I needed was comment out Content-Type.

  Post(endpoint, postData) {
    let auth = `Bearer ${this.token}`;
    let headers = new HttpHeaders({
      // "Content-Type": "application/x-www-form-urlencoded",
      Authorization: auth
    });
    let fullurl = `${this.baseUrl}${endpoint}`;
   .....
  ....
}
0
M A Rahul On

There is a minor difference between Django and Django Rest Framework whenever we try to add the Foreign key references to an instance

Let us assume we want to add the user references to another DB Table

Django

In Django, we reference the whole instance of the user as mentioned below

user = request.user

Django Rest Framework

However in DRF if we follow the same procedure we get the errors like

Incorrect type. Expected pk value, received str/User type

In order to overcome this error, we need to reference the Primary Key of the table instead (Here id is the PK)

user = request.user.id