Django序列化器报错:期望字典却得到User对象
解决DRF序列化自定义User模型时的"Expected a dictionary, but got User"错误
问题描述
尝试通过API展示自定义User模型字段时,序列化器验证失败,报错:
{"non_field_errors": ["Invalid data. Expected a dictionary, but got User."]}
以下是相关代码:
自定义User模型
from django.db import models from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin class UserManager(BaseUserManager): def _create_user(self, username, password, is_staff, is_superuser, **extra_fields): user = self.model( username=username, is_staff=is_staff, is_superuser=is_superuser, **extra_fields ) user.set_password(password) user.save(using=self.db) return user def create_user(self, username, password=None, **extra_fields): return self._create_user(username, password, False, False, **extra_fields) def create_superuser(self, username, password=None, **extra_fields): return self._create_user(username, password, True, True, **extra_fields) class User(AbstractBaseUser, PermissionsMixin): username = models.CharField(max_length=255, unique=True) email = models.EmailField( max_length=255, blank=True, null=True) name = models.CharField(max_length=255, blank=True, null=True) age = models.PositiveIntegerField() is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'username' REQUIRED_FIELDS = [] def __str__(self): return f"{self.id} {self.name} {self.username} {self.age}"
序列化器代码
class UserUpdateSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'email', 'username', 'name', 'age']
视图代码
class UserUpdateApiView(APIView): def get(self, request, pk): try: queryset = User.objects.get(pk=pk) serializer = UserUpdateSerializer(data=queryset) if serializer.is_valid(raise_exception=True): return Response(data=serializer.data) except User.DoesNotExist: return Response(data={"error": "User no found"}, status=status.HTTP_404_NOT_FOUND)
错误原因
核心问题是序列化器初始化传参错误:
data参数用于反序列化场景(接收前端传入的字典数据,创建/更新模型实例);- 当你要序列化已存在的模型实例(从数据库查询到的User对象),应该直接将实例传入序列化器的
instance参数(可省略参数名,直接传第一个位置参数)。
此外,get方法是返回已有数据,不需要调用serializer.is_valid()——该方法仅用于反序列化时验证输入数据,序列化实例时无需验证。
修复方案
1. 修正视图代码
修改视图中序列化器的初始化方式,并移除不必要的验证步骤:
class UserUpdateApiView(APIView): def get(self, request, pk): try: user = User.objects.get(pk=pk) serializer = UserUpdateSerializer(user) # 直接传入实例,无需data参数 return Response(data=serializer.data) except User.DoesNotExist: return Response(data={"error": "User not found"}, status=status.HTTP_404_NOT_FOUND)
2. 修正UserManager的缩进错误
原模型中UserManager的_create_user方法存在缩进问题,会导致用户创建逻辑失效,修正后:
class UserManager(BaseUserManager): def _create_user(self, username, password, is_staff, is_superuser, **extra_fields): user = self.model( username=username, is_staff=is_staff, is_superuser=is_superuser, **extra_fields ) user.set_password(password) user.save(using=self._db) # 注意这里是self._db,不是self.db return user def create_user(self, username, password=None, **extra_fields): return self._create_user(username, password, False, False, **extra_fields) def create_superuser(self, username, password=None, **extra_fields): return self._create_user(username, password, True, True, **extra_fields)
内容的提问来源于stack exchange,提问作者Lucin Husein
相关产品推荐
相关产品推荐

