Reputation: 1372
I'm trying to add data to my database. To this purpuse, I have a vue function :
@api_view(['POST'])
def update_add_bges(request):
serializer = BGESSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
this one call a serializer to add new data in the database :
class BGESSerializer(serializers.ModelSerializer):
laboratoire = LaboratoiresSerializer()
class Meta:
model = BGES
fields = '__all__'
def create(self, validated_data):
laboratoire_data = validated_data.pop('laboratoire')
laboratoire_oj = Laboratoire.objects.create(**laboratoire_data)
validated_data["laboratoire"] = laboratoire_obj["pk"]
bges = BGES.objects.create(**validated_data)
return bges
The problem is that my Laboratoire classe is nested as well, and should add instances from an other class :
class LaboratoiresSerializer(serializers.ModelSerializer):
tutelles = TutellesSerializer(many=True)
class Meta:
model = Laboratoire
fields = '__all__'
def create(self, validated_data):
tutelles_data = validated_data.pop('tutelles')
laboratoire = Laboratoire.objects.create(**validated_data)
for tutelle_data in tutelles_data:
t = Tutelle.objects.get(nom=tutelle_data["nom"])
laboratoire.tutelles.add(t)
return laboratoire
This is not working, because not called as it's the create of the serializer and not the create of the Models. How should I do ? When I add a Laboratoire, I have Tutelle to create ... Should I implement the create in the Models ? As I am new to django, I have hard time to understand the subtility of functions calls.
Upvotes: 0
Views: 351
Reputation: 20682
You are asking to create a writable nested serializer when you have a depth of 2, i.e. two nested serializers. Fortunately, you've already written the code in LaboratoireSerializer
that creates the Laboratoire
and Tutelle
objects based on validated_data
, so you can do this:
class BGESSerializer(serializers.ModelSerializer):
class Meta:
model = Laboratoire
fields = '__all__'
depth = 2
def create(self, validated_data):
laboratoire_data = validated_data.pop('laboratoire')
laboratoire_obj = LaboratoireSerializer.create(self, laboratoire_data) # note we don't instantiate the serializer!
validated_data["laboratoire"] = laboratoire_obj # note we pass the object not pk
bges = BGES.objects.create(**validated_data)
return bges
The trick here is to call the method create
on the class, passing self
into it. It works because the create
method doesn't actually care about self
and doesn't use it. I wouldn't work if self
was used in the create
method of LaboratoireSerializer
and expected to be a LaboratoireSerializer
. It's hacky, I know, but it works.
Upvotes: 1