Joabe da Luz
Joabe da Luz

Reputation: 1020

Django rest framework nested serialization not working properly

I have these serializers in my app:

class ScheduleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Schedule
        fields = ('id',)

class DisciplineSerializer(serializers.ModelSerializer):
    class Meta:
        model = Discipline
        fields = ('id',)


class WriteTeacherSerializer(serializers.ModelSerializer):
    disciplines = DisciplineSerializer(many=True)
    schedules = ScheduleSerializer(many=True)
    class Meta:
        model = Teacher
        fields = ('phone_number', 'bio', 'price', 'disciplines', 'schedules')
        depth = 1

    def update(self, instance, validated_data):

        print "\n"
        #Debugging here
        print validated_data
        print "\n"
        print instance.__dict__
        print "\n"

        instance.phone_number = validated_data['phone_number']
        instance.bio = validated_data['bio']
        instance.price = validated_data['price']
        disciplines = validated_data.pop('disciplines')
        schedules = validated_data.pop('schedules')
        for discipline in disciplines:
            try:
                stored_discipline = Discipline.objects.get(id=discipline['id'])
                instance.disciplines.add(stored_discipline)
            except Discipline.DoesNotExist:
                raise Http404

        for schedule in schedules:
            try:
                stored_schedule = Schedule.objects.get(id=schedule['id'])
                instance.schedules.add(stored_discipline)
            except Discipline.DoesNotExist:
                raise Http404
        instance.save()
        return instance

As you can see I am trying a nested serialization with the fields schedules and disciplines. I think I followed the documentation, but the nested serialization is not working when I test it. I printed the instance and validated_data objects and tested it on the shell.

I start the data in this format:

data = {u'phone_number': u'+99999999999', u'bio': u'BIO', u'price': 40, u'disciplines': [{'id': 1}], u'schedules': [{'id': 2}]}

I got a teacher instance and started the serializer like this:

serializer = WriteTeacherSerializer(teacher, data=data)

It shows True on a serializer.is_valid() call.

However when I try to save it the validated_data and the instance.__dict__ are like that:

#validated_data
{u'phone_number': u'+5584998727770', u'bio': u'BIO', u'price': 40, u'disciplines': [OrderedDict()], u'schedules': [OrderedDict()]}


#instance.__dict__
{'phone_number': u'', 'bio': u'', 'price': 50, 'profile_id': 2, '_state': <django.db.models.base.ModelState object at 0xb64a6bec>, 'id': 6}

They don't seem to notice the nested fields wich makes the update() method not work.

Am I doing something wrong?

Here is my Teacher Model as well:

class Teacher(models.Model):

    price = models.IntegerField(default=50)
    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Wrong phone number format.")
    phone_number = models.CharField(validators=[phone_regex], max_length=15, blank=True)
    profile = models.OneToOneField(Profile, on_delete=models.CASCADE)
    schedules = models.ManyToManyField(Schedule, related_name='schedules')
    disciplines = models.ManyToManyField(Discipline, related_name='disciplines')
    bio = models.CharField(max_length=200, blank=True)

Upvotes: 3

Views: 2552

Answers (1)

Aaron Lelevier
Aaron Lelevier

Reputation: 20800

If you are just sending IDs then you don't need to add the nested serializer, just specify the field name of the ForeignKey or ManyToManyField.

class WriteTeacherSerializer(serializers.ModelSerializer):

    class Meta:
        model = Teacher
        fields = ('phone_number', 'bio', 'price', 'disciplines', 'schedules')

I am also wondering if it is because you have a depth=1 flag?

DRF doesn't support nested updates out of the box. You have to override the Serializer's update method, and write your own update logic, so you'd be seeing an error for this warning if you were sending nested data.

Upvotes: 2

Related Questions