【问题标题】:Django Rest Framework Serializer Relations: How to get list of all child objects in parent's serializer?Django Rest Framework 序列化器关系:如何获取父序列化器中所有子对象的列表?
【发布时间】:2016-02-24 12:13:28
【问题描述】:

我是 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 Serializer Relations 进行了创建,如下所示:

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'},
        ...
    ],
}

我没想到这会起作用,因为在 Parent 模型 but it is the suggested way to do it in the documentation 中 Parent 和 Child 之间没有链接,并且它不起作用。

我收到以下错误消息:

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'.

我认为这是完全合理的,但我无法理解我在这里缺少什么。

如何获取父序列化程序中所有子节点的列表?

【问题讨论】:

  • 我相信后向关系的相关名称默认为{field_name}_set,所以在本例中为children_set。您应该可以在您的ParentSerializer 中将children 替换为children_set

标签: python django serialization django-rest-framework


【解决方案1】:

您可以通过两种方式实现:

  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. 每个字段都可以是模型的属性或方法,所以你可以在Parent模型中定义一个get_children_list方法,然后在ParentSerializer的字段列表中调用它:

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

注意:在这种情况下,您需要从serializers.ModelSerializer 继承

【讨论】:

  • 感谢您的回答。对于第一个,我得到同样的错误:'Parent' object has no attribute 'child_list'
  • 我说,child_list 是您的 Parent 类中的一个方法,它返回子列表
  • 你也可以通过 obj.children_set.all() 获得子节点集
【解决方案2】:

我认为您的问题是您忘记为您的 Children 模型添加 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)

而且我认为通过此更改,您将解决您遇到的错误

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 2014-07-07
    相关资源
    最近更新 更多