重写Django模型save()方法后更新失败,报唯一约束冲突
Django模型save方法更新时触发IntegrityError的解决办法
自定义Person模型重写save()方法后,新增记录功能正常,但更新现有记录时抛出IntegrityError: UNIQUE constraint failed: members_person.id错误。
错误原因
重写save方法时,调用父类save方法错误地传递了self参数。Django模型的save是实例方法,通过super()调用时无需手动传入self,多余的self会被当作force_insert参数(save方法的第一个位置参数),导致更新操作被强制转为插入操作——而现有记录的id已存在,因此触发唯一约束冲突。
修复方案
将super().save(self, *args, **kwargs)修改为super().save(*args, **kwargs),移除多余的self参数。
修复后的完整模型代码:
class Person(models.Model): SHIRT_SIZES = [ ("S", "Small"), ("M", "Medium"), ("L", "Large"), ] first_name = models.CharField("person's first name:", max_length=30, help_text="User First name") last_name = models.CharField("Person's Last Name:", max_length=30, help_text="User Last name") shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES, default="S", help_text="User shirt size") def __str__(self) -> str: return self.first_name + ' ' + self.last_name def full_name(self): return '%s %s' %(self.first_name, self.last_name) def get_absolute_url(self): return "/people/%i/" % self.id; def save(self, *args, **kwargs): self.first_name = "%s %s" %('Mr', self.first_name) # 移除多余的self参数 return super().save(*args, **kwargs)
补充说明
调用super().save()时,Python会自动将当前实例绑定到父类的save方法上,无需手动传入self。错误传入self会导致参数错位,让Django误判为执行插入操作,最终触发id字段的唯一约束错误。
内容的提问来源于stack exchange,提问作者Tushar
相关产品推荐
相关产品推荐

