Django REST Framework报错:int()参数类型错误,如何传递认证用户至user字段?
你遇到的问题根源在于:perform_create里你传了user_id=self.request.user,但self.request.user是Django的SimpleLazyObject(它是一个延迟加载的对象,直到你访问它的属性时才会解析成实际的User实例),而user_id字段需要的是整数类型的用户ID,直接传递就触发了类型错误。
这里有两种更优雅的解决方式,推荐第一种:
方法一:直接传递User实例给serializer.save()
这是DRF中处理关联用户的标准做法,不需要手动处理ID:
- 修改
contacts/views.py里的perform_create方法:
def perform_create(self, serializer): serializer.save(user=self.request.user)
- 更新
contacts/serializers.py里的create方法,接收额外的user参数:
def create(self, validated_data, user=None): phone_numbers = validated_data.pop('contactphonenumber_set') # 注意:你的代码里有一行`emails = validated_data.pop('contactemail_set')`,但打印的validated_data里没有这个字段, # 如果你的Contact模型没有关联的ContactEmail表,建议删掉这行,否则会触发KeyError instance = Contact.objects.create(user=user, **validated_data) for phone_data in phone_numbers: ContactPhoneNumber.objects.create(contact=instance, **phone_data) return instance
为什么这样有效?
当你调用serializer.save(user=self.request.user)时,DRF会把user这个额外参数传递给create方法。此时user已经是解析后的User实例(因为作为参数传递触发了SimpleLazyObject的解析),直接赋值给Contact的user外键字段即可,Django会自动处理关联关系,不需要手动传ID。
方法二:手动解析SimpleLazyObject获取用户ID
如果你坚持要传user_id,可以先获取用户的ID(访问self.request.user.id会触发SimpleLazyObject解析,得到整数ID):
修改perform_create:
def perform_create(self, serializer): serializer.save(user_id=self.request.user.id)
这种情况下不需要修改serializer的create方法,因为user_id参数会直接传递给Contact.objects.create(),Django ORM能直接识别并使用这个ID值。
不过这种方法不如第一种直观,推荐用方法一,因为它更符合DRF和Django的ORM设计习惯。
另外,检查一下你的ContactSerializer的create方法里的emails = validated_data.pop('contactemail_set'),如果你的Contact模型没有对应的ContactEmail关联表,这行代码会导致KeyError,建议根据实际情况删除或补充相关逻辑。
内容的提问来源于stack exchange,提问作者Anuj TBE

