繁体   English   中英

将自定义查询集传递给 django rest 框架嵌套序列化程序

[英]pass custom queryset to django rest framework nested serializer

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

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 中所做的那样,但这不会自动发生。 这里的任何帮助都会挽救我的生命。 我花了一整天的时间试图实现这一目标,但每次都失败了。

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

首先,我准备"counter_party"子查询,其中我对所有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"))
    )

然后我 select 来自 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}
    )

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM