Django用户注册报错UNIQUE约束失败,寻求解决方案
问题原因
错误django.db.utils.IntegrityError: UNIQUE constraint failed: accounts_profile.user_id的核心原因是重复创建一对一关联的Profile实例:
- 执行
super().save(request)创建User后,signals.py中注册的post_save信号会自动为新User创建一个Profile; - 紧接着
CustomRegisterSerializer.save()方法里又调用Profile.objects.create(user=user, user_type=user_type),尝试为同一个User再创建一个Profile,违反了OneToOneField的唯一约束。
解决方案
两种可行修复方式,选其一即可:
方式一:移除冗余的信号逻辑(推荐)
直接删除signals.py中自动创建Profile的代码,序列化器已经负责处理Profile的创建,无需信号重复执行:
# signals.py 注释或删除以下代码 # @receiver(post_save, sender=User) # def create_user_profile(sender, instance, created, **kwargs): # if created: # Profile.objects.create(user=instance, user_type='') # post_save.connect(create_user_profile, sender=User)
方式二:修改序列化器的save方法,避免重复创建
若需保留信号(不推荐,冗余),将序列化器中的Profile.objects.create替换为get_or_create:
# serializer.py def save(self, request): user = super().save(request) user_type = self.validated_data.get('user_type') # 用get_or_create避免重复创建 Profile.objects.get_or_create(user=user, defaults={'user_type': user_type}) return user
额外优化建议
CustomRegisterSerializer中Meta.fields = "__all__"会暴露User模型的所有字段(如is_superuser),建议显式指定需要的字段:class Meta: model = User fields = ('username', 'email', 'password1', 'password2', 'user_type')- Profile模型中的
base_type可直接整合到user_type的default中,无需单独定义变量:user_type = models.CharField(choices=Type.choices, default=Type.seeker, max_length=20)
内容的提问来源于stack exchange,提问作者Vicente Antonio G. Reyes
相关产品推荐
相关产品推荐

