【问题标题】:Get separate serializer response for each nested serializer为每个嵌套的序列化器获取单独的序列化器响应
【发布时间】:2021-07-21 02:46:56
【问题描述】:

卡在序列化程序中,我需要基于嵌套序列化程序进行序列化响应。

模型.py:

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

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

Serialziers.py

class ChildSerializer(serializers.ModelSerializer):
    class Meta:
        model = Child
        fields = '__all__'

class ParentSerializer(serializers.ModelSerializer):
    child = serializers.SerializerMethodField()
    
    def get_child(self, obj):
        childs = Child.objects.filter(parent=obj)
        return ChildSerializer(childs, many=True).data

    class Meta:
        model = Parent
        fields = '__all__'

我得到如下输出,我得到嵌套的孩子:

{
    id : 1,
    name : "Parent1",
    child: [
        0: {id : 1, child_name : "child1"}
        1: {id : 2, child_name : "child2"}
    ]
}

但出于某些业务目的,我需要输出如下所示,其中序列化程序应基于子级。即对于每个孩子应该有单独的父序列化程序。如果它具有相同的 id 和其他字段都没关系。 :

{
    0:{
        id : 1,
        name : "Parent1",
        child: [
            0: {id : 1, child_name : "child1"}
        ]
    }
    1:{
        id : 1,
        name : "Parent1",
        child: [
            0: {id : 2, child_name : "child2"}
        ]
    }
}

另外请告诉我是否可以根据子序列化程序进行过滤。即childs 我将传递给父序列化程序并获得每个孩子的响应。

【问题讨论】:

  • 每个对象有一个孩子时,为什么需要列出孩子?
  • 如果在 ChildSerializer 和 ChildSerializer 相关视图中添加parent = ParentSerializer(),您的问题没有解决?
  • 它的列表,因为我保留了many=True。但问题不在于...如果我将ParentSerializer 保留在子序列化程序中,那么序列化程序响应格式将被更改...并且我想保持相同的格式...

标签: django django-rest-framework django-serializer


【解决方案1】:

尝试如下更改Parent Serializer

class ParentSerializer(serializers.ModelSerializer):

    children = ChildSerializer(read_only=True)

    def to_representation(self, instance):
        child_query = Child.objects.filter(parent=instance)
        num_childs = child_query.count()
        ret_instance = {}
        for idx in range(num_childs):
            children = ChildSerializer(child_query[idx:idx + 1], many=True).data
            for child in children:
                child.pop('parent', None)
            temp_dict = {
              'id': instance.id,
              'name': instance.name,
              'child': children
            }
            ret_instance[idx] = temp_dict
        return ret_instance 

    class Meta:
        model = Parent
        fields = '__all__'

要更改序列化程序响应的表示,需要使用to_representation() 方法。

【讨论】:

    【解决方案2】:

    我直接在父序列化器中传递了childs对象,并根据它进行过滤。这对我有用。

    class ChildSerializer(serializers.ModelSerializer):
        class Meta:
            model = Child
            fields = '__all__'
    
    class ParentSerializer(serializers.ModelSerializer):
        name = serializers.ReadOnlyField(source='parent.name')
        child = serializers.SerializerMethodField()
        
        def get_child(self, obj):
            childs = Child.objects.filter(id=obj.id)
            return ChildSerializer(childs, many=True).data
    
        class Meta:
            model = Parent
            fields = ("childs", "name")
    

    然后在parent中直接传递子对象。

    child = Child.objects.all()
    ParentSerializer(child, many=True)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 2017-07-28
      • 2017-07-12
      相关资源
      最近更新 更多