【问题标题】:Get all items with all properties using django multi-table inheritance and django rest framework使用 django 多表继承和 django rest 框架获取具有所有属性的所有项目
【发布时间】:2020-04-02 17:09:29
【问题描述】:

我正在使用 Django 多表继承:

class Parent():
   common_property = ...

class Child1(Parent):
   child1_specific_property = ...

class Child2(Parent):
   child2_specific_property = ...

并希望在同一端点上公开所有项的列表。

如果我为Parent 模型创建一个基本的序列化程序和视图,我将只获得公共属性(存在于该模型上的那些),但在这种情况下,我想获得每个项目的所有子特定属性.理想情况下是这样的:

items {
    type_1: {
      common_property
      child1_specific_property
    }
    type_2: {
      common_property
      child2_specific_property
    }
}

我错过了任何简单的方法吗?

【问题讨论】:

  • 没有简单的方法可以做到这一点。 django-polymorphic 是一个自动获取正确类的子模型的包。还有其他包做类似的事情。

标签: python django django-rest-framework


【解决方案1】:

我最终找到了一种 很好 执行方式来手动执行此操作。正如@dirkgroten 评论的那样,更简单的选择是使用django-polymorphic 之类的库。

模型是使用多表继承定义的,如我的问题所述:

class Parent():
   common_property = ...

class Child1(Parent):
   child1_specific_property = ...

class Child2(Parent):
   child2_specific_property = ...

序列化器上,我们覆盖to_representation 方法以便将每个实例映射到正确的子序列化器:

from rest_framework import serializers


class Parent(serializers.BaseSerializer):

    def to_representation(self, instance):

        try:
            return Child_1_Serializer(instance=instance.child1).data
        except Child1.DoesNotExist:
            pass

        try:
            return Child_2_Serializer(instance=instance.child2).data
        except Child2.DoesNotExist:
            pass

        return super().to_representation(instance)

视图上,我们在定义查询集时使用select_related,以避免在获取列表时对每个孩子执行一次查询。有关select_related 的更多信息,请访问Queryset API reference

class ParentViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Parent.objects.all().select_related('child1').select_related('child2')
    serializer_class = ParentSerializer

过滤器和其他东西可以像使用简单模型一样添加到序列化程序中。

【讨论】:

    猜你喜欢
    • 2013-07-02
    • 2018-10-09
    • 1970-01-01
    • 2019-07-13
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    相关资源
    最近更新 更多