如何处理多个相关对象(在对象中嵌套)

时间:2016-01-22 04:42:37

标签: django django-rest-framework

由于我的数据库设计方式,图像不会与项目一起存储。

这是因为每个产品没有设定数量的图像。有些可能有1张图片,有些可能有10张。

我希望我的API能够返回嵌套在其中的内容。目前,我的代码只是在项目存在其他图像时重复整个对象。

我正在使用Django Rest Framework:

class ProductDetailView(APIView):

    renderer_classes = (JSONRenderer, )

    def get(self, request, *args, **kwargs):

        filters = {}
        for key, value in request.GET.items():
            key = key.lower()
            if key in productdetailmatch:
                lookup, val = productdetailmatch[key](value.lower())
                filters[lookup] = val

        qset = (
            Product.objects
            .filter(**filters)
            .values('pk', 'brand')
            .annotate(
                image=F('variation__image__image'),
                price=F('variation__price__price'),
                name=F('variation__name'),
            )
        )

        return Response(qset)

目前,有3个图像指向它的项目将如下所示:

[{
        "name": "Amplitiue jet black",
        "brand": "Allup",
        "price": "$1248",
        "vari": "917439",
        "image": "url1",
    },
    {
        "name": "Amplitiue jet black",
        "brand": "Allup",
        "price": "$1248",
        "vari": "917439",
        "image": "url",
    },
    {
        "name": "Amplitiue jet black",
        "brand": "Allup",
        "price": "$1248",
        "vari": "917439",
        "image": "url",
    },

理想情况下,它应该如下所示,将数组中的所有图像组合在一起:

{
    "name": "Amplitiue jet black",
    "brand": "Allup",
    "price": "$1248",
    "vari": "917439",
    "images": [
        "url1",
        "url2"
        "url3"
    ],
}

1 个答案:

答案 0 :(得分:0)

您应该使用ListApiViewModelSerializer。不要将过滤放在get方法中,基于Django类的视图方式是使用get_queryset

from rest_framework import serializers, generics

class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ("url",)

class ProductSerializer(serializers.ModelSerializer):
    images = ImageSerializer(many=True)
    class Meta:
        model = Product
        fields = ("name", "brand", "price", "vari", "images")

class ProductListView(generics.ListAPIView): # it is not a details view 
    serializer_class = ProductSerializer
    def get_queryset(self):
        filters = {}
        for key, value in self.request.GET.items():
            key = key.lower()
            if key in productdetailmatch:
                lookup, val = productdetailmatch[key](value.lower())
                filters[lookup] = val
         return Product.objects.prefetch_related("images").filter(**filters)

JSON中的图像列表将是具有一个“url”元素的对象,而不仅仅是一个url列表,但无论如何这都与REST标准更加一致。