【问题标题】:How to retrieve models data having nested relationship using serializers in Django Rest Framework?如何使用 Django Rest Framework 中的序列化程序检索具有嵌套关系的模型数据?
【发布时间】:2018-09-15 05:07:30
【问题描述】:

我正在详细解释我面临的一个问题,并向这个社区寻求帮助。我关注了这个Django Rest Framework documentation,但无法获得多级嵌套所需的结果

按照解释考虑模型之间的关系:

  1. 一个用户可以有多个工作区
  2. 一个工作区可以有多个项目
  3. 一个项目可以有多个项目列表
  4. ProjectList 可以有多个任务
  5. 任务可以有多个更新

User | Workspaces (ForeignKey="User") |____Projects (ForeignKey="Workspaces") |____TodoList (ForeignKey="Projects") |____Tasks (ForeignKey="TodoList") |____Updates (ForeignKey="Tasks")

所以我想要的是以嵌套 json 格式获取用户拥有的所有数据,如下所示:

[
    {
        "workspace_id": "99a961ec-b89e-11e8-96f8-529269fb1459",
        "workspace_owner": "1",
        "workspace_title": "Indie Dev Works",
        "projects": [
            {
                "project_id":"db09cfa0-b89e-11e8-96f8-529269fb1459",
                "todo_list":[
                    {
                        "list_id": "9dc64e4c-b89f-11e8-96f8-529269fb1459",
                        "list_name":"Project list -1",
                        "tasks":[
                            "task_name":"Create HTML docs",
                            "updates":[
                                {
                                    "id":"d5eb660e-b89f-11e8-96f8-529269fb1459",
                                    "text":"Creating using PUG"
                                },
                                {
                                    .....
                                    .....
                                    .....
                                    .....

                                },

                            ]

                        ]
                    }
                ]

            },

            {
                "project_id":".........",
                ....
                ....
                ....
                ..
                ..
                .


            },
        ]

    }
]

所以当我的用户通过输入电子邮件登录时,我试图获取所有 Workspaces 实例,然后将其传递给序列化程序 在我看来如下所述:

views.py

class InitializeHome(viewsets.ViewSet):

    def list(self,request):
        user_email = request.user.email
        user_instance = utils.getUserInstance(user_email)
        workspace_instance = WorkSpace.objects.filter(workspace_owner=user_instance)

        testing_serializer = WorkSpaceSerializer(workspace_instance,many=True)
        return Response(testing_serializer.data)

serializers.py

class UpdateSerializer(serializers.ModelSerializer):

    class Meta:
        # depth = 2        
        fields = '__all__'
        model = Update


class TaskSerializer(serializers.ModelSerializer):
    updates = UpdateSerializer(many=True,read_only=True)
    class Meta:
        # depth = 2        
        fields = '__all__'   
        model = Task


class ProjectTodoListSerializer(serializers.ModelSerializer):
    tasks = TaskSerializer(many=True,read_only=True)
    class Meta:
        # depth = 2        
        fields =  '__all__'
        model = ProjectTodoListItem


class ProjectSerializer(serializers.ModelSerializer):


    project_todo_list = ProjectTodoListItemSerializer(many=True,read_only=True)                
    class Meta:
        # depth = 2        
        fields = '__all__'
        model = Project


class WorkSpaceSerializer(serializers.ModelSerializer):

    projects = ProjectSerializer(many=True,read_only=True)
    class Meta:
        # depth = 2

        model = WorkSpace
        fields = '__all__'

我得到的只是这个,没有嵌套数组:

[
    {
        "id": 1,
        "workspace_title": "Indie Dev Work",
        "status": "ACTIVE",
        "workspace_id": "26c60d80-c018-403c-84b2-d92f01f6fb7e",
        "workspace_owner": 1
    },
    {
        "id": 2,
        "workspace_title": "Homework Space",
        "status": "ACTIVE",
        "workspace_id": "08c715cc-bd24-46d3-a1dd-14cf7ff28215",
        "workspace_owner": 1
    }
]

【问题讨论】:

    标签: python django django-models django-rest-framework


    【解决方案1】:

    找到了答案。 通过在所有的Serializer类中添加source="workspace_set",可以达到效果:-

    class WorkSpaceSerializer(serializers.ModelSerializer):
    
        projects = ProjectSerializer(many=True,read_only=True,source="workspace_set")
        class Meta:
            # depth = 2
    
            model = WorkSpace
            fields = '__all__'
    

    【讨论】:

    【解决方案2】:

    你也可以试试这个方法:

    class WorkSpaceSerializer(serializers.ModelSerializer):
    
        class Meta:
            # depth = 2
    
            model = WorkSpace
            fields = '__all__'
    
        def get_projects(self, obj): # get_YOUR_FIELD_NAME
            return ProjectSerializer(obj.projects.all(), many=True).data
    

    其他类也一样。

    我不确定为什么您的代码不起作用,我现在无法真正测试它,但您可以尝试在元类中命名字段(它应该没有任何区别,但您可以尝试)

    【讨论】:

    • 你好,谢谢你的回复。如果我们将 source 参数添加到序列化程序类中,那么我们可以获得所需的结果。看看我的回答
    猜你喜欢
    • 2016-07-28
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多