首页 > 解决方案 > 将两个模型实例组合成一个序列化对象 django rest framework

问题描述

如何合并相等的字段并将不同的值附加到返回的响应中的字段中,而不依赖于对象的数量?访问 enpoint 时,我目前得到以下响应:

[
    {
        "colors": [
            "Red",
            "Orange",
        ],
        "styles": [
            "Rock"
        ],
        "application": [
            "Wall"
        ],
        "material": [
            "Mosaic"
        ]
    },
    {
        "colors": [
            "Yellow",
        ],
        "styles": [
            "Mosaic"
        ],
        "application": [
            "Wall"
        ],
        "material": [
            "Ceramic"
        ]
    }
]

虽然想要实现类似于下面的代码片段,其中附加了唯一值并合并了相等的字段:

[
    {
        "colors": [
            "Red",
            "Orange",
            "Yellow"
        ],
        "styles": [
            "Rock"
            "Mosaic"
        ],
        "application": [
            "Wall"
        ],
        "material": [
            "Mosaic"
            "Ceramic"
        ]
    },
]

我的序列化程序的结构如下:

class ProductFiltersByCategorySerializer(serializers.ModelSerializer):
    """
    A serializer to display available filters for a product lust 
    """

    colors = serializers.StringRelatedField(read_only=True, many=True)
    styles = serializers.StringRelatedField(read_only=True, many=True)
    application = serializers.StringRelatedField(read_only=True, many=True)
    material = serializers.StringRelatedField(read_only=True, many=True)

    class Meta:
        model = Product
        fields = (
            'colors',
            'styles',
            'application',
            'material'
        )

我的视图集结构如下:

class ProductFiltersByCategory(generics.ListAPIView):
    """
    This viewset takes the category parameter from the url and returns related product filters
    """

    serializer_class = ProductFiltersByCategorySerializer

    def get_queryset(self):

        category = self.kwargs['category']
        return Product.objects.filter(category__parent__name__iexact=category).distinct()

字段颜色、样式、应用和材料与产品模型中的它们自己的模型是多对多关系。5

更新 1:(模型)

class ProductSize(models.Model):
    ...


class ProductColor(models.Model):
    ...


class ProductStyle(models.Model):
    ...


class ProductApplication(models.Model):
    ...


class ProductMaterial(models.Model):
    ...


class Product(models.Model):

    ...
    colors = models.ManyToManyField(
        ProductColor,
        related_name='product_color'
    )
    styles = models.ManyToManyField(
        ProductStyle,
        related_name='product_style'
    )
    application = models.ManyToManyField(
        ProductApplication,
        related_name='product_application'
    )
    material = models.ManyToManyField(
        ProductMaterial,
        related_name='product_material'
    )
    absorption = models.FloatField(
        null=True,
        blank=True
    )
    ...

标签: djangodjango-rest-framework

解决方案


这是因为您的查询返回两个对象,每个对象都有一些相关字段。序列化程序分别序列化每个对象,因此您应该合并视图中负责应用程序逻辑的字段,为此,如果您的数据库是 postgres,您可以使用如下代码:

from django.contrib.postgres.aggregates import ArrayAgg    
Product.objects.filter(category__parent__name__iexact=category).distinct().aggregate(colors_field=ArrayAgg('colors__name'))

或者您可以为每个字段编写单独的查询。


推荐阅读