14

Related to this Topic


Hi, I cannot follow the answer at the attached topic, because an ID is missing after serialization.

  • Model.py

class Owner(models.Model):
    name = models.CharField(db_index=True, max_length=200)

class Car(models.Model):
    name = models.CharField(db_index=True, max_length=200)
    LCVS  = models.ForeignKey(Owner)
  • View.py

class OwnerViewSet(viewsets.ModelViewSet):
    queryset = Owner.objects.all()
    serializer_class = OwnerSerializer

class CarViewSet(viewsets.ModelViewSet):
    serializer_class = CarSerializer
    queryset = Car.objects.all()
  • Serializer.py

class OwnerSerializer(serializers.ModelSerializer):
    class Meta:
        model =  Owner
        fields = ('id', 'name')

class CarSerializer(serializers.ModelSerializer):
    owner = OwnerSerializer() 

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

    def create(self, validated_data):
        tmp_owner = Owner.objects.get(id=validated_data["car"]["id"])
        car = Car.objects.create(name=self.data['name'],owner=tmp_owner)
        return car

Now i send the following request :

Request URL:http://localhost:9000/api/v1/cars
Request Method:POST
Request Paylod :
{
    "name": "Car_test", 
    "ower": {
        "id":1,
        "name": "Owner_test"
    }
}

But, here the validated_data don't contain the owner ID !

Traceback | Local vars

 validated_data {u'Owner': OrderedDict([(u'name', u'Owner_test')]), u'name': u'Car_test'} 

@Kevin Brown :
Workful ! Thanks I'll validate your answer but I get a new problem...

Now when I try to put a new Owner, an error raise :

{
    "id": [
        "This field is required."
    ]
}

I had to create a new serializer ?

Community
  • 1
  • 1
CheapD AKA Ju
  • 713
  • 2
  • 7
  • 21
  • I am guessing you mean `id=validated_data["owner"]["id"]` and that you mean `LCVS=tmp_owner`. Also it should not be needed to get the owner object. Just create with: `car = Car.objects.create(name= validated_data['name'],LCVS_id=validated_data["owner"]["id"])` – Christoffer May 07 '15 at 11:11

1 Answers1

31

Any AutoFields on your model (which is what the automatically generated id key is) are set to read-only by default when Django REST Framework is creating fields in the background. You can confirm this by doing

repr(CarSerializer())

and seeing the field generated with read_only=True set. You can override this with the extra_kwargs Meta option which will allow you to override it and set read_only=False.

class OwnerSerializer(serializers.ModelSerializer):

    class Meta:
        model =  Owner
        fields = ('id', 'name')
        extra_kwargs = {
            "id": {
                "read_only": False,
                "required": False,
            },
        }

This will include the id field in the validated_data when you need it.

Kevin Brown-Silva
  • 40,873
  • 40
  • 203
  • 237
  • Thanks, Can you help me a bit more ? I edit the Topic – CheapD AKA Ju Jan 09 '15 at 16:05
  • Also set `required=False` (updated my answer). I would also recommend creating new questions on Stack Overflow if you have additional questions to avoid invalidating existing answers. :) – Kevin Brown-Silva Jan 09 '15 at 16:13
  • Really you rox, I don't know how I could have found that ! – CheapD AKA Ju Jan 09 '15 at 16:23
  • Had same issue. Applied the same logic but serializer.is_valid() is false. I had foreignkey constraint on patient_id & doctor_id while creating appointment models object. & it was giving null on both foreign key id's in serializer.data. This id's are shown after i implemented above solution but I guess its not taking patient object and doctor object and only taking int(id). Hence serializer.is_valid() gave false and didnt create appointment object. any other way which I can create object in appointment table with patient_id and doctor_id as foreign_key instances of respective models? – patilkrunal Feb 02 '21 at 15:21