Seaux
Seaux

Reputation: 3517

Django Rest Framework Nested Serializer Existing Instance

I have a nested ModelSerializer that I'm having trouble validating.

The problem I'm running into is that upon parent serializer creation I may or may not need to create the nested serializer/model as it may already exist in the database and I just want to link to it.

Code Setup:

models.py

class ModelA(models.Model):
    modelb = ForeignKey(ModelB, null=true, blank=true)
    ...

class ModelB(models.Model):
    ...

serializers.py

class ModelASerializer(serializers.ModelSerializer):
    modelb = ModelBSerializer(required=False)

    class Meta:
        model = ModelA
        depth = 1

class ModelBSerializer(serializers.ModelSerializer):
    class Meta:
        model = ModelB

So, given 3 data scenarios I run into validation errors on all 3.

First, if I pass the NestedModel as data like so

data = {
    'nestedmodel': NestedModel(**args),
    ...
}

I get the validation error saying there was a non_field_error and that it was expecting a dictionary but got a NestedModel instance.

Second, if I pass the data of the NestedModel (instead of the object):

data = {
    'nestedmodel': {'id': 'this', ... },
}

I get the validation error equivalent of a duplicate key since the Nested Model has a unique key ('id') and that already exists in the database.

And third, if I just pass it the id of the nestedmodel, I get a similar error to the first situation except it says it got Unicode instead of the NestedModel instance.

data = {
    'nestedmodel': 'this',
}

I understand why all three of these situations are happening and validation is failing, but that doesn't help me in my goal of trying to link an already existing NestedModel.

How do I go about doing that? What am I doing wrong?

Upvotes: 3

Views: 2015

Answers (1)

Seenu S
Seenu S

Reputation: 3481

Can you try this:

serializers.py

class ModelASerializer(serializers.ModelSerializer):
    modelb = ModelBSerializer(required=False)

    class Meta:
        model = ModelA
        depth = 1
        fields = ('id', 'modelb', )

    def create(self, validated_data):
        modelb_id = self.validated_data.pop("nestedmodel")
        modelb = ModelB.objects.get(id=modelb_id["id"])
        modela = ModelA.objects.create(modelb=modelb, **validated_data)
        return modela

Pass the data as follows:

Input

data = {"nestedmodel": {"id": 1 # add nestedmodel fields here}, }


          

Upvotes: 1

Related Questions