【问题标题】:pass custom queryset to django rest framework nested serializer将自定义查询集传递给 django rest 框架嵌套序列化程序
【发布时间】:2021-04-28 10:38:51
【问题描述】:

我有以下格式的序列化程序:

CounterPartyCompanySerializer:

class CounterPartyCompanySerializer(serializers.ModelSerializer):
class Meta:
    model = ClientCompany
    fields = (
        "id",
        "company_name",
        "address_line1",
    )
    extra_kwargs = {
        "id": {
            "read_only": False,
            "required": False,
        },
    }

CounterPartySerializer:

class CounterPartySerializer(serializers.ModelSerializer):
company = CounterPartyCompanySerializer()

class Meta:
    model = Client
    fields = (
        "id",
        "company",
        "client_name",
    )
    extra_kwargs = {
        "id": {
            "read_only": False,
            "required": False,
        },
    }

和 GiftAndEntertainmentSerializer:

class GiftAndEntertainmentSerializer(serializers.ModelSerializer):
counter_party = CounterPartySerializer()

class Meta:
    model = GiftAndEntertainment
    fields = (
        "id",
        "counter_party",
        "value",

    )

Case-I :: 当我执行以下操作时它会起作用:

result_list = GiftAndEntertainment.objects.all()

    serializer = GiftAndEntertainmentSerializer(
        result_list, many=True, context={"request": request}
    )

但是,当我传递自定义查询集时它不起作用:

result_list = GiftAndEntertainment.objects.values(
        "counter_party",
        "value"
    ).annotate(
        total=ExpressionWrapper(Sum("value"), output_field=DecimalField())
    )

    serializer = GiftAndEntertainmentSerializer(
        result_list, many=True, context={"request": request}
    )

这里,"counter_party" 是 ForeignKey 映射实体,查询集通过 counter_party 实体的 primary-key id。我认为序列化程序会将 pk 转换为其相应的实体,就像它在 case-I 中所做的那样,但这不会自动发生。这里的任何帮助都会挽救我的生命。我花了一整天的时间试图实现这一目标,但每次都失败了。

【问题讨论】:

    标签: python django serialization django-rest-framework


    【解决方案1】:

    SO 线程的帮助下,我能够实现这一目标。我所做的是:

    首先,我准备 GiftAndEntertainment 子查询,其中我对所有 value 字段求和,并将主键 id 标记为 pk 用于外部查询。

    from django.db.models import ExpressionWrapper, DecimalField, Subquery, Sum, OuterRef
    
        group_by = (
            GiftAndEntertainment.objects.values(
                "counter_party"
            )
            .annotate(
                total=ExpressionWrapper(
                    Sum("value"), output_field=DecimalField()
                )
            )
            .filter(id=OuterRef("pk"))
        )
    

    然后我从 GiftAndEntertainment 加上子查询结果中选择所有行作为row_value 字段。

        group_by_with_total = GiftAndEntertainment.objects.annotate(
            row_value=Subquery(group_by.values("total"))
        )
    
        serializer = GiftAndEntertainmentSerializer(
            group_by_with_total, many=True, context={"request": request}
        )
    

    这样,序列化程序很高兴地接受了查询集,甚至自动映射了相应的实体。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-27
      • 1970-01-01
      • 2016-08-06
      • 2021-06-23
      • 2019-12-23
      • 2016-05-14
      • 2016-09-25
      • 2018-12-13
      相关资源
      最近更新 更多