首页 > 解决方案 > 如何在 django rest 框架中序列化多个查询集?

问题描述

我有两个相互关联的模型。一个代表一个项目,另一个代表该项目所属的领域/区域。

我有一个看起来像这样的视图:

class ProjetosArea(generics.ListAPIView):
    lookup_field = 'id'
    serializer_class = ProjetosPreviaSerializer
    pagination_class = ProjectPagination

    def get_queryset(self):
        area_id = self.kwargs['id']

        area = AreaConhecimento.objects.get(id=area_id)
        projetos = Projeto.objects.filter(area_conhecimento=area_id)

        queryset =  [area, projetos]

        return queryset

我想为此视图编写一个序列化程序,如下所示:

{
   "area": {---fields of the area---},
   "projects": [---The projects that belongs to that area---]
}

如何为此编写序列化程序?查询集是一个包含该区域和属于该区域的项目的列表

标签: pythondjangodjango-rest-framework

解决方案


get_queryset看起来不对。这个想法是在那里返回一个查询集以在那里执行权限检查等。你不应该像这样返回两个资源。

虽然如果您需要它 - 代码只是一个工具。随心所欲地使用它。


我建议保持get_queryset原样并覆盖list方法,因为那是您真正想要做的。因为您要返回两个资源,所以它需要知道如何处理它们。

从示例中,我推断area_conhecimento为 area pk。所以这样的事情应该有效。

class ProjetosArea(generics.ListAPIView):
    lookup_field = 'area_conhecimento'
    serializer_class = ProjetosAreaSerializer
    pagination_class = ProjectPagination

    def list(self, request, *args, **kwargs):
        qs = self.filter_queryset(self.get_queryset())

        area = qs.first().area_conhecimento

        # you will have to adjust it for pagination
        serializer = self.get_serializer({
            'projects': qs,
            'area': area
        })
        return Response(serializer.data)

只是序列化器就这么简单。

from rest_framework import serializers


class AreaConhecimentoSerializer(serializers.ModelSerializer):
    class Meta:
        model = AreaConhecimento
        fields = '__all__'


class ProjetoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Projeto
        fields = '__all__'


class ProjetosAreaSerializer(serializers.Serializer):
    area = AreaConhecimentoSerializer(read_only=True)
    projects = ProjetoSerializer(many=True, read_only=True)


但是您真正的问题是您实际上想要获得区域及其项目。所以就去做吧。你自己说The projects that belongs to that area的。

class AreaRetrieveAPIView(RetrieveAPIView):
    serializer_class = AreaSerializer
    pagination_class = AreaPagination


class ProjetoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Projeto
        fields = '__all__'
        

class AreaSerializer(serializers.ModelSerializer):
    projeto = ProjetoSerializer(many=True, read_only=True)
    
    class Meta:
        model = AreaConhecimento
        fields = '__all__'

它会回来

{
   "area": {
        "projects": [---The projects that belongs to that area---],
         ---fields of the area---
    },
}

推荐阅读