Подтвердить что ты не робот

Django Rest Framework Сериализаторы: как получить список всех дочерних объектов в родительском сериализаторе?

Я новичок в DRF и только что начал создавать API. У меня две модели, дочерняя модель связана с родительской моделью с внешним ключом. Вот упрощенная версия модели, которую я имею:

class Parent(models.Model):
    name = models.CharField(max_length=50)


class Child(models.Model):
    parent = models.ForeignKey(Parent)
    child_name = models.CharField(max_length=80)

Чтобы создать сериализаторы, я последовал за отношениями Serializer DRF, и я создал их как следующие:

class ChildSerializer(serializers.HyperlinkedModelSerializer):

    parent_id = serializers.PrimaryKeyRelatedField(queryset=Parent.objects.all(),source='parent.id')

    class Meta:
        model = Child
        fields = ('url','id','child_name','parent_id')

    def create(self, validated_data):
        subject = Child.objects.create(parent=validated_data['parent']['id'], child_name=validated_data['child_name'])

        return child


class ParentSerializer(serializers.HyperlinkedModelSerializer):
    children = ChildSerializer(many=True, read_only=True)
    class Meta:
        model = Course
        fields = ('url','id','name','children')

Я пытаюсь получить список всех дочерних элементов в родительском сериализаторе. Я хочу, чтобы получить ответ вроде этого:

{
    'url': 'https://dummyapidomain.com/parents/1/',  
    'id': '1',
    'name': 'Dummy Parent Name',
    'cildren': [
        {'id': 1, 'child_name': 'Dummy Children I'},
        {'id': 2, 'child_name': 'Dummy Children II'},
        {'id': 3, 'child_name': 'Dummy Children III'},
        ...
    ],
}

Я не ожидал, что это сработает, поскольку в родительской модели нет связи между родителем и ребенком, но это предложенный способ сделать это в документации, и это не сработало.

Появляется следующее сообщение об ошибке:

Got AttributeError when attempting to get a value for field `children` on serializer `ParentSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Parent` instance.
Original exception text was: 'Parent' object has no attribute 'children'.

Я думаю, что это вполне разумно, но я не мог понять, чего мне здесь не хватает.

Как получить список всех дочерних элементов в родительском сериализаторе?

4b9b3361

Ответ 1

Я думаю, ваша проблема заключается в том, что вы забыли добавить related_name для своей модели для детей. У меня были бы такие модели:

class Parent(models.Model):
    name = models.CharField(max_length=50)

class Child(models.Model):
    parent = models.ForeignKey(Parent, related_name='children')  # <--- Add related_name
    child_name = models.CharField(max_length=80)

И я думаю, что с этим изменением вы решите ошибку, получая

Ответ 2

Вы можете реализовать это двумя способами:

  • С SerializerMethodField: ваш код стал следующим:

    class ParentSerializer(serializers.ModelSerializer):
    
         children_list = serializers.SerializerMethodField('_get_children')
    
         def _get_children(self, obj):
             serializer = ChildSerializer(obj.child_list(), many=True)
             return serializer.data
    
        class Meta:
            model = Course
            fields = ('url','id','name','children_list')
    
  • Каждое поле может быть атрибутом модели или метода, поэтому вы можете определить метод get_children_list в модели Parent, а затем вызвать его в списке полей ParentSerializer:

    class ParentSerializer(serializers.ModelSerializer):
    
        class Meta:
             model = Course
             fields = ('url','id','name','get_children_list')
    

Примечание: вам нужно наследовать от serializers.ModelSerializer в этом сценарии