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

使用Django REST Framework嵌套序列化器遇AttributeError问题求助

问题:嵌套序列化器序列化时触发AttributeError

错误信息:

AttributeError: 尝试获取UserSerializer上的email字段值时触发AttributeError。序列化器字段名称可能不正确,与UserSerializer实例的任何属性或键都不匹配。原始异常信息为:'UserSerializer' object has no attribute 'email'。

相关代码

models.py

class Notification(models.Model):
    kind = models.IntegerField(default=0)
    message = models.CharField(max_length=256)

class User(AbstractUser):
    username = models.CharField(max_length=150, blank=True, null=True)
    email = models.EmailField(unique=True)
    customer_id = models.UUIDField(default=uuid.uuid4, editable=False)

serializers.py

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = [
            "id",
            "first_name",
            "last_name",
            "email",
            "customer_id"
        ]

class NotificationSerializer(serializers.ModelSerializer):

    class Meta:
        model = Notification
        fields = [
            "id",
            "kind",
            "message",
        ]

class UserLoginSerializer(serializers.Serializer):
    user_info = UserSerializer(read_only=True)
    notifications = NotificationSerializer(many=True, read_only=True)

视图端点代码

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": UserSerializer(request.user),
            "notifications": NotificationSerializer(notifications, many=True),
        }
    )
    return Response(serializer.data)

错误原因

你给UserLoginSerializer传递的user_info和notifications参数是序列化器实例,但UserLoginSerializer的这两个字段本身就是序列化器类型,它期望接收的是模型实例/查询集这类原始数据,而不是已经初始化的序列化器对象。

当UserLoginSerializer尝试用UserSerializer去序列化传入的UserSerializer实例时,会去读取这个实例的email属性,而UserSerializer类本身并没有email属性,因此触发了AttributeError。


修复方案

直接给UserLoginSerializer传递模型实例和查询集即可,不需要提前调用序列化器初始化:

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": request.user,
            "notifications": notifications,
        }
    )
    return Response(serializer.data)

如果确实需要提前处理序列化后的数据(比如添加额外自定义字段),可以传递序列化器的.data属性(即已经序列化完成的字典数据):

def get_login_info(self, request):
    notifications = Notification.objects.filter(recipient=request.user)
    serializer = UserLoginSerializer(
        {
            "user_info": UserSerializer(request.user).data,
            "notifications": NotificationSerializer(notifications, many=True).data,
        }
    )
    return Response(serializer.data)

推荐使用第一种方案,更符合DRF的序列化器设计逻辑。


内容的提问来源于stack exchange,提问作者Dylan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:41:30