【问题标题】:Serialization of parent model including child models父模型的序列化,包括子模型
【发布时间】:2018-11-30 19:30:01
【问题描述】:

我有模特 - 商品、服装和儿童模特,如配饰、外套等:

class Commodity(models.Model):
    atribute = models.CharField()

class Clother(models.Model):
    commodity = models.ForeignKey(Commodity)
    clother_atribute = models.CharField()

class Acessories(models.Model):
    clother = models.ForeignKey(Clother)
    acessories_atribute = models.CharField() 

class Outwear(models.Model):
    clother = models.ForeignKey(Clother)
    outwear_atribute = models.CharField()

如何序列化父模型Commodity来调用所有垂直依赖?我想查询 Commodity id 并获取所有 Clother 属性和 Acessories 或 Outwear 属性。

【问题讨论】:

  • 你使用 Django 序列化器吗?
  • 我使用 Django REST Framework 模型序列化器。
  • 好吧,既然 Django 中没有像“垂直依赖”这样的概念,你可能必须自己列出这些。是的,您可以浏览模型关系图,但检测循环会使事情变得复杂。
  • 谢谢,注意了。希望能遇到这样的事情。

标签: django django-models django-rest-framework


【解决方案1】:

如果我理解您的问题,您可以定义ClotherSerializer。您可以使用depth = 1 序列化此序列化程序中的嵌套对象:

class ClotherSerializer(serializers.ModelSerializer):
    class Meta:
        model = Clother
        fields = ('id', 'acessories_set', 'outwear_set')
        depth = 1

稍后在您的CommoditySerializer 中,您可以使用ClotherSerializer 序列化服装及其所有关系:

class CommoditySerializer(serializers.ModelSerializer):
    clother_set = ClotherSerializer(many=True)
    class Meta:
        model = Commodity
        fields = ('id', 'clother_set')

【讨论】:

  • 你真的可以在parent的对象中传递一个children列表,同时创建一个parent和多个children吗?已经尝试过,但由于某种原因,父对象似乎不接受子对象列表,尽管它们的关系已在其模型中明确定义。有关如何管理此问题的任何提示?
  • @Seb 尝试检查文档中的可写嵌套序列化程序部分:django-rest-framework.org/api-guide/relations/…
  • 感谢您的回复。所以已经尝试但仍然收到错误“无效数据。需要字典,但得到列表。”在对应于其子级的父级对象字段中。当我在孩子和父母之间有多对一的关系时,为什么它会这样表现?
【解决方案2】:

或者,这也可以使用SerializerMethodFieldhttp://www.django-rest-framework.org/api-guide/fields/#serializermethodfield来实现

class ClotherSerializer(serializers.ModelSerializer):
    """
    Serializer for Clother data model.
    """
    acessories = serializers.SerializerMethodField()
    outwears = serializers.SerializerMethodField()

    class Meta:
        model = Clother
        fields = ('id', 'acessories', 'outwears')

    def get_acessories(self, clother):
        return AcessoriesSerializer(clother.acessories_set.all(), many=True).data

    def get_outwears(self, clother):
        return OutwearSerializer(clother.outwear_set.all(), many=True).data


class CommoditySerializer(serializers.ModelSerializer):
    """
    Serializer for Commodity data model.
    """
    clother = serializers.SerializerMethodField()

    class Meta:
        model = Commodity
        fields = ('id', 'clother')

    def get_clother(self, commodity):
        return ClotherSerializer(commodity.clother_set.all(), many=True).data

【讨论】:

    【解决方案3】:

    您可以为此使用drf-writable-nested [GitHub] 包并在序列化程序中指定如何 序列化某些字段。通过使用另一个序列化器,您可以通过调用这些子序列化器来指定它对其进行序列化:

    class CommoditySerializer(WritableNestedModelSerializer):
        clother_set = ClotherSerializer(many=True)
    
        class Meta:
            model = Commodity
            fields = ("atribute", 'clother_set')
    
    
    class ClotherSerializer(WritableNestedModelSerializer):
    
        class Meta:
            model = Clother
            fields = ("clother_atribute",)

    当然你可以添加更多这样的关系,例如为Clother指定Acessories

    我建议您查看 GitHub 页面,并将其用作您自己的序列化程序的模板。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多