【问题标题】:Serializing Related Data in Django using Natural Foregin Keys (Three Models, Two Layers)使用自然外键序列化 Django 中的相关数据(三个模型,两层)
【发布时间】:2022-01-13 18:43:41
【问题描述】:

我有三个模型,ProductProductReleaseReleaseNote,它们都继承自抽象模型工厂(具有公共字段),具有以下关系:

class Product(abstract_base_model_factory()):
    <additional fields>

class ProductRelease(abstract_base_model_factory()):
    <additional fields>
    product = models.ForeignKey(Product, on_delete=models.CASCADE,
                                related_name='product_releases')

class ReleaseNote(abstract_base_model_factory()):
    <additional fields>
    product_release = models.ForeignKey(ProductRelease, on_delete=models.CASCADE,
                                        related_name='release_notes')

我已按照文档对这些进行序列化以返回 JSON。我使用docs here 来设置自然键的序列化。

如果需要,我可以添加额外的代码,但它主要是样板代码,并且适用于两个模型(ProductReleaseProductReleaseNoteProductRelease)。但它不适用于三个模型。

例如,如果我序列化ProductRelease 对象,我可以看到Product 和我指定的字段:

{
  "product_releases": [
    {
      "model": "products.productrelease", 
      "pk": 7, 
      "fields": {
          "name": "Product Release A",
          "product": "prod1"
      }
    },
    { . . . },
  ]
}

但是,我希望能够序列化 ReleaseNote 对象,然后显示 ProductRelease(第一个外键关系) Product(第二个外键关系)对象。

这可以在单个 JSON 响应中完成,而无需使用 Django REST Framework 之类的包吗?我想在不需要额外软件包的情况下实现这一点。

更新

一段时间后,我意识到@oleksii 是对的。我最终实现了 Django REST 框架并得到了我需要的嵌套。效果很好。

【问题讨论】:

    标签: django serialization django-related-manager


    【解决方案1】:

    您可以将嵌套模型序列化程序用于您的目的,如下所示:

    class ProductSerializer(serializers.ModelSerializer):
        class Meta:
            model = Product
            fields = "__all__"
    
    class ProductReleaseSerializer(serializers.ModelSerializer):
        product = ProductSerializer(many=True)
    
        class Meta:
            model = ProductRelease
            fields = "__all__"
    
    
    class ReleaseNoteSerializer(serializers.ModelSerializer):
        product_release = ProductReleaseSerializer()
    
        class Meta:
            model = ReleaseNote
            fields = "__all__"
    
    release_note_model_instance = ReleaseNote.objects.all()
    print(ReleaseNoteSerializer(release_note_model_instance, many=True).data)
    

    【讨论】:

    • 我是否需要many=TrueProductSerializerProductReleaseSerializer,因为每个关系都可能有很多?另外,serializers.ModelSerializer 似乎是 Django REST 框架的一部分,不是吗?我没有使用那个包...
    • 在您的情况下,每个ReleaseNote 实例仅包含一个ProductRelease,因为product_release 是一个外键。 ProductReleaseProduct 相同。但总的来说,是的,您可以使用many=True。是的,ModelSerializer 是 Django REST 框架的一部分。你可以找到文档here
    • 谢谢。由于我没有使用 Django REST Framework,因此您的答案不适用于此处。你知道如何在没有 DRF 的情况下实现我的目标吗?我考虑过使用它,但现在我正在寻找一种不需要额外软件包的解决方案。
    • 我想,你唯一的解决方案就是使用natural keys。但我推荐使用 Django REST Framework,它是 Django 中序列化复杂结构对象的经典方式。
    • 正如我最初的问题中所述,我使用自然键并按照文档到达我所在的位置。我可以在双模型场景中使用自然键就好了(这是文档概述的内容),但是当我输入第三个时,它变得复杂了。我知道 Django REST Framework 是用于序列化复杂数据的 de facto 方法,但我希望在没有额外包的情况下得到答案。任何建议都会受到赞赏,但我知道这可能是一个艰难的建议,因为 DRF 并不常见。再次感谢您的宝贵时间。
    猜你喜欢
    • 2020-02-08
    • 1970-01-01
    • 2011-04-30
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 2020-10-26
    • 1970-01-01
    相关资源
    最近更新 更多