使用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
相关产品推荐
相关产品推荐

