I'm trying to create two model instances from a single post request. Model2 is linked to Model1 using a ForeignKey field. Model1 also has a validate() in its serializer. The issue is when I use nested serializer to save both model instances together, the validate function of Model1 returns an error AttributeError: 'Model1Serializer' object has no attribute 'initial_data'.
If the data keyword argument is not passed then the
.initial_dataattribute will not exist.
Trials: I tried intercepting the flow in __init__() and validate() of CombinedSerializer but it seems, the validate() of Model1Serializer is evaluated first.
Doubt: Why is the Model1Serializer not getting supplied with the data keyword argument and how can I correct my code? At what stage is the Model1Serializer validate() function evaluated?
Models:
from django.db import models
class Model1(models.Model):
key1 = models.PositiveIntegerField(blank=False, null=False)
def __str__(self):
return self.key1
class Model2(models.Model):
foreign_key = models.ForeignKey('Model1', blank=True, null=True, on_delete=models.CASCADE)
key2 = models.CharField(max_length=20)
def __str__(self):
return self.key2
Serializers:
from rest_framework import serializers
from .models import Model1, Model2
class Model1Serializer(serializers.ModelSerializer):
def validate(self, data):
if(self.initial_data['key1']>=10):
data['key1'] = self.initial_data['key1'] + 1
return data
else:
data['key1'] = self.initial_data['key1']
return data
class Meta:
model = Model1
fields = '__all__'
class Model2Serializer(serializers.ModelSerializer):
class Meta:
model = Model2
fields = '__all__'
class CombinedModelSerializer(serializers.ModelSerializer):
model1 = Model1Serializer()
model2 = Model2Serializer()
def create(self, validated_data):
model2_data = validated_data.pop('model2')
model1 = Model1.objects.create(**validated_data)
model2 = Model2.objects.create(foreign_key=model1.id, **model2_data)
return model1
class Meta:
model = Model1
fields = '__all__'
Views:
from django.shortcuts import render
from rest_framework import generics
from .models import Model1, Model2
from .serializers import Model1Serializer, Model2Serializer, CombinedModelSerializer
class Model1List(generics.ListCreateAPIView):
queryset = Model1.objects.all()
serializer_class = Model1Serializer
class Model2List(generics.ListCreateAPIView):
queryset = Model2.objects.all()
serializer_class = Model2Serializer
class CombinedList(generics.ListCreateAPIView):
queryset = Model1.objects.all()
serializer_class = CombinedModelSerializer
Post Request:
POST: http://127.0.0.1:8000/combined/
{
"model1":
{
"key1": 45
},
"model2": {
"key2": "val2"
}
}
Package Versions:
Python==3.6.8
Django==2.2.4
djangorestframework==3.10.3
Model1Serializer? I don't understand what the current validator is doing.Model1.