You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django序列化嵌套JSON时userSerializer报AttributeError解决

嵌套JSON接口问题排查与修正

报错直接原因

你组装返回数据时逻辑错位,传给子序列化器的user字段值是字符串而非用户对象列表;同时嵌套字段的序列化配置错误,DRF执行序列化时,子序列化器在字符串实例上查找email/username属性,就触发了AttributeError。

逐文件问题定位

Serializer 层问题

  • 顶层字段名和需求不匹配:需求返回的字段是rule,代码里写的是rules,字段名不一致会导致取数失败。
  • 嵌套字段的source参数配置错误:source='*'代表将整个当前对象作为值传给子序列化器,和你要取对象中存储用户列表的字典键值的需求完全不符。
  • 字段映射和View返回的数据结构没有做对齐,没有明确告诉DRF从哪个键读取用户列表数据。

View 层问题

  • 核心组装逻辑错误:你用dict(zip(keys, row))组装返回字典时,第二个参数row是dictfetchall返回的字典对象,直接迭代字典得到的是字典的键名而非对应的值。最终拼出来的字典里,user键对应的值是字符串'details',根本不是用户列表。
  • 子查询参数逻辑错误:循环父规则数据时,子查询传入的参数是全局登录用户,没有传入当前循环规则的关联标识,会导致所有规则拿到完全相同的用户列表,不符合业务逻辑。
  • 用户列表存储的键名错误:你已经通过dictfetchall把子查询结果转成了带email/username的字典列表,却硬编码赋值给了data['details'],没有把用户列表存到Serializer期望的user键下。
  • 父数据组装键名不匹配:硬编码的键元组里rules是复数,和实际数据里的rule字段名不一致,就算组装逻辑对了,也会出现字段值取不到的问题。
  • 子查询SQL存在语法错误:代码里子查询字符串末尾多了一个右括号,会导致SQL执行失败。
  • 冗余逻辑:循环内部每次都把全量父数据转成JSON打印,没有实际业务作用,还会增加接口开销。

修正后可直接运行的代码

serializer.py

from rest_framework import serializers

class UserSerializer(serializers.Serializer):
    email = serializers.CharField()
    username = serializers.CharField()


class CloudScoreAnalysisSerializer(serializers.Serializer):
    # 字段名和需求返回结构完全对齐
    rule = serializers.CharField()
    criticality = serializers.CharField()
    # 移除错误的source配置,默认从对象的user键读取用户列表
    user = UserSerializer(many=True)

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.db import connection

class ScoreAnalysisView(APIView):
    def queryset_scoreAnalysisView(self, user):
        cursor = connection.cursor()
        child_cursor = connection.cursor()
        # 执行父查询:获取当前用户关联的所有规则数据
        cursor.execute("你的父数据MySQL查询SQL", (user,))
        parent_rows = self.dictfetchall(cursor)

        result = []
        for row in parent_rows:
            # 传入当前规则的关联标识到子查询,替换成你实际表结构的关联字段
            current_related_id = row["规则关联字段名"]
            # 执行子查询:获取当前规则关联的所有用户数据
            child_cursor.execute("你的子数据MySQL查询SQL", (current_related_id,))
            user_rows = self.dictfetchall(child_cursor)
            # 组装和Serializer结构完全匹配的字典
            result.append({
                "rule": row["rule"],
                "criticality": row["criticality"],
                "user": user_rows
            })
        return result

    def get(self, request):
        result = self.queryset_scoreAnalysisView(request.user)
        serializer = CloudScoreAnalysisSerializer(result, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def dictfetchall(self, cursor):
        "Returns all rows from a cursor as a dict"
        desc = cursor.description
        return [
            dict(zip([col[0] for col in desc], row))
            for row in cursor.fetchall()
        ]

代码调整后,接口会返回你需求中指定的嵌套JSON结构,不会再触发字段匹配的AttributeError。

内容的提问来源于stack exchange,提问作者Anurag Kumar Pandey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 15:15:05