Отношения сериализатора 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)

чтобы создать сериализаторы, я следовал отношения сериализатора 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'.

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

как я могу получить список всех детей в сериализатор родителей?

2 ответов


Я думаю, ваша проблема в том, что вы забыли добавить 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)

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


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

  1. С 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')
    
  2. каждое поле может быть атрибутом модели или метода, поэтому вы можете определить метод get_children_list в Parent модель, затем назовите ее в списке полей ParentSerializer:

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

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