Django运行报'User' object has no attribute 'rank'错误如何解决?
错误原因
报错核心是你把Django内置User模型的实例传给了只适配UserProfile模型的UserProfileSerializer:
rank、major等字段是定义在你自己写的UserProfile模型上的,Django默认的User模型本身没有这些属性- 从错误栈可以看到,调用链路是
QuestionSerializer的get_user方法调用了UserProfileSerializer,你给这个序列化器传的参数是User实例,不是对应的UserProfile实例,所以执行get_rank方法访问obj.rank时直接抛出属性错误
修复方案
两种方案选一种即可:
方案1:修改Question序列化器的传参逻辑(更推荐)
找到你question/serializers.py里第67行附近的get_user方法,原来的逻辑应该是直接把Question关联的User实例传给了UserProfileSerializer,改成先取User关联的UserProfile实例再传入:
# 假设你的Question模型关联用户的字段名为author,根据你的实际字段名修改 def get_user(self, obj): # User和UserProfile是一对一关联,默认反向关联名为userprofile # 如果你在OneToOneField里设置了related_name,就用你自定义的名称 user_profile = obj.author.userprofile return UserProfileSerializer(user_profile, many=False).data
如果存在部分User没有创建对应UserProfile的情况,加个异常捕获避免报错:
def get_user(self, obj): try: user_profile = obj.author.userprofile except UserProfile.DoesNotExist: return None return UserProfileSerializer(user_profile, many=False).data
方案2:修改UserProfileSerializer兼容User实例
如果你的业务场景里确实需要经常给这个序列化器传User实例,可以修改UserProfileSerializer里的自定义字段方法,先判断实例类型再取对应属性:
def get_rank(self,obj): # 兼容传入User实例的情况 if hasattr(obj, 'userprofile'): obj = obj.userprofile rank = obj.rank return RankSerializer(rank,many=False).data if rank else None def get_major(self,obj): if hasattr(obj, 'userprofile'): obj = obj.userprofile major = obj.major return MajorSerializer(major,many=False).data if major else None def get_profile_pic(self, obj): if hasattr(obj, 'userprofile'): obj = obj.userprofile try: pic = obj.profile_pic.url except: pic = None return pic
额外优化建议
- 你
UserProfile模型里的username字段可以删掉,直接从关联的user字段取即可,避免数据冗余同步问题 - 外键的
related_name命名不合理,比如Major外键的related_name="major",建议改成user_profiles这类符合反向关联语义的名称
内容的提问来源于stack exchange,提问作者amirhossein delkhosh
相关产品推荐
相关产品推荐

