Django中查询关联User的ConsumerModel报错,求解决方法
问题排查与解决方法
错误点分析
- 序列化验证失效:
serializer.is_valid是方法对象,未执行调用,导致无论传入数据是否合法,都会进入后续逻辑。 - 字符串拼接类型错误:
print语句中试图将ConsumerModel实例直接与字符串相加,Python不允许对象与字符串直接拼接,会抛出TypeError。 - 模型
__str__方法错误:ConsumerModel的__str__返回self.user(User对象)而非字符串,当user为None时还会触发AttributeError,同时影响实例转字符串的场景。 - 未捕获
ConsumerModel不存在异常:找到User后,若对应的ConsumerModel不存在,get方法会抛出ConsumerModel.DoesNotExist,导致程序崩溃。
修复后的代码
1. 修复ConsumerModel的__str__方法
class ConsumerModel(models.Model): GENDER_LIST = ( ('male','MALE'), ('female','FEMALE'), ("lgbt",'LGBT') ) REGISTER_AS = ( ('consumer','CONSUMER'), ('manager','MANAGER') ) uid = models.CharField(max_length=8) # 可添加默认值避免创建实例时报错 profile_id = models.UUIDField(default=uuid.uuid4) user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True) name = models.CharField(max_length=40) birthdate = models.DateField(null=True,blank=True) mobile_number = models.CharField(max_length=12, null=True, blank=True) gender = models.CharField(max_length=20,choices=GENDER_LIST,null=True,blank=True) profile_image = models.ImageField(null=True,blank=True,upload_to="images/") # 修正null与blank的逻辑矛盾,根据业务调整为必填或可选 register_as = models.CharField(null=False, blank=False,choices=REGISTER_AS, max_length=12) def __str__(self): # 返回字符串类型,优先显示name,其次是用户账号,最后用uid兜底 if self.name: return self.name elif self.user: return str(self.user) return f"Consumer {self.uid}"
2. 修复视图逻辑
serializer = ConsumerLoginSerializer(data=request_data) # 修复:调用is_valid()方法执行验证 if serializer.is_valid(): try: user = User.objects.get(email=request_data["email"]) except User.DoesNotExist: return Response( data={'status': wrong_input, 'message': wrong_body_vals_msg, 'errors': {"Email":"User not found"}}, status=400 ) try: consumer = ConsumerModel.objects.get(user=user) # 修复:访问实例的profile_id属性,或转字符串后拼接 print(f"PROFILE ID: {consumer.profile_id}") except ConsumerModel.DoesNotExist: return Response( data={'status': wrong_input, 'message': "Consumer profile not found"}, status=404 ) return Response(data={"status": ok, 'message': "Success"}, status=ok) else: # 新增:返回序列化错误信息 return Response( data={'status': wrong_input, 'message': wrong_body_vals_msg, 'errors': serializer.errors}, status=400 )
额外优化说明
profile_id字段添加default=uuid.uuid4(需提前导入uuid模块),避免创建实例时因缺少该字段值报错。register_as字段原null=True, blank=False逻辑矛盾,数据库允许空值但表单不允许,建议统一为null=False, blank=False(必填)或根据业务需求调整为可选。
内容的提问来源于stack exchange,提问作者corneliusstone
相关产品推荐
相关产品推荐

