我已经搜索了类似的主题,但没有找到一个解决方案,为我的特定情况。我有一个User
扩展模型,另外还有UserProfile
来扩展和存储一些用户信息。UserProfile
与User
模型有 * OneToOne
* 关系。我有一个User
模型save
方法被覆盖,以立即在User
对象上创建一个UserProfile
对象。但是每当我创建一个新的User
示例**IntegrityError UNIQUE constraint failed: accounts_userprofile.user_id
时,即使两个示例(User和UserProfile)都成功创建,也会引发。在创建用户(甚至是超级用户)后,每当我尝试登录Django Admin时,我都得到相同的IntegrityError UNIQUE constraint failed: accounts_userprofile.user_id
**。
我试过:
1.应用迁移(以防万一);
1.完全删除数据库,从头开始重复所有内容;
我知道有一种方法可以将OneToOne关系更改为ForeignKey,但如果有其他解决方案,我希望保留这种关系。
models.py:
class UserManager(BaseUserManager):
def create_user(self, email, password, **kwargs):
if not email:
raise ValueError("Please, provide a correct email.")
email = self.normalize_email(email)
user = self.model(email=email, **kwargs)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **kwargs):
kwargs.setdefault('is_staff', True)
kwargs.setdefault('is_superuser', True)
kwargs.setdefault('is_active', True)
if not kwargs.get('is_staff'):
raise ValueError("Superuser must have 'is_staff' value set to True")
if not kwargs.get('is_superuser'):
raise ValueError("Superuser must have 'is_superuser' value set to True")
if not kwargs.get('is_active'):
raise ValueError("Superuser must have 'is_active' value set to True")
return self.create_user(email, password, **kwargs)
class User(AbstractBaseUser, PermissionsMixin):
""" Custom user model """
objects = UserManager()
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
email = models.EmailField(max_length=255, unique=True)
password = models.CharField(max_length=128, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
USERNAME_FIELD = "email"
def save(self, *args, **kwargs):
super(User, self).save(*args, **kwargs)
UserProfile.objects.create(user=self)
class UserProfile(models.Model):
GENDER_CHOICES = (
('male', 'Male'),
('female', 'Female')
)
first_name = models.CharField(max_length=250, null=True, blank=True)
last_name = models.CharField(max_length=250, null=True, blank=True)
gender = models.CharField(max_length=10, choices=GENDER_CHOICES, null=True, blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
serializers.py:
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(
write_only=True,
required=True
)
class Meta:
model = get_user_model()
fields = (
"id",
"password",
"email",
"profile_link",
"created_at",
"updated_at"
)
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = "__all__"
我不明白为什么在登录到管理面板时代码**UserProfile.objects.create(user=self)
**上的这一行出现错误。为什么登录时一直执行save
方法?
更新:
如果我删除分配给用户尝试登录的UserProfile对象,则不会出现IntegrityError。
2条答案
按热度按时间btqmn9zl1#
因为当你登录时,Django会更新last_login字段并运行保存方法。在这种情况下,UserProfile创建行将引发错误。
我的建议是不要在保存方法上创建UserProfile,你可以为那个signals使用create信号
如果你想使用你的方式,你可以使用get_or_create
velaa5lx2#
因为当你登录时,Django会更新last_login字段并运行保存方法。在这种情况下,UserProfile创建行将引发错误。
我的建议是不要在保存方法上创建UserProfile,你可以为那个信号使用create signal
如果你想使用你的方式,你可以使用get_or_create
如果您更喜欢使用
get_or_create
,这将很好地工作,但这也会在每次登录时触发不必要的查询。我会考虑用它来做一个小小的改进: