更新时间:2022-12-05 20:49:35
可以通过将 primary_key = True
OneToOneField
指向用户
模型,就像您已经弄清楚一样。
The problem can be avoided by setting primary_key=True
on the OneToOneField
pointing at the User
model, as you have figured out yourself.
这个工作原理似乎很简单。
The reason that this works seems to be rather simple.
当您尝试创建一个模型实例并设置 pk
手动保存之前,Django将尝试使用 pk
在数据库中查找记录,并进行更新,而不是盲目地尝试创建一个新的。如果没有,则按预期创建新记录。
When you try to create a model instance and set the pk
manually before saving it, Django will try to find a record in the database with that pk
and update it rather than blindly attempting to create a new one. If none exists, it creates the new record as expected.
当您将 OneToOneField
设置为主键时, Django Admin将该字段设置为相关的用户
模型的ID,这意味着 pk
已经设置,Django会尝试找到现有记录。
When you set the OneToOneField
as the primary key and Django Admin sets that field to the related User
model's ID, that means the pk
is already set and Django will attempt to find an existing record first.
这是将 OneToOneField
设置为主键的情况:
This is what happens with the OneToOneField
set as primary key:
用户
实例,没有 id 。
用户
实例。 User
instance, with no id
.User
instance.
pk
(在这种情况下 id
)是未设置,Django尝试创建新记录。 id
由数据库自动设置。 post_save
钩子为该用户创建一个新的配置文件
实例
实例。pk
(in this case id
) is not set, Django attempts to create a new record.id
is set automatically by the database.post_save
hook creates a new Profile
instance for that User
instance.
个人资料
实例,其用户
设置为用户的 id
。配置文件
实例。 Profile
instance, with its user
set to the user's id
.Profile
instance.
pk
(在这种情况下 user
)是已经设置好,Django尝试使用 pk
获取现有记录。pk
(in this case user
) is already set, Django attempts to fetch an existing record with that pk
.
如果没有显式设置主键,Django会添加一个使用数据库的 auto_increment
功能:数据库将 pk
设置为不存在的下一个最大值。这意味着该字段实际上将保留为空白,除非您手动设置,否则Django将始终尝试插入新记录,导致与 OneToOneField
之间的唯一性约束产生冲突>。
If you don't set the primary key explicitly, Django instead adds a field that uses the database's auto_increment
functionality: the database sets the pk
to the next largest value that doesn't exist. This means the field will actually be left blank unless you set it manually and Django will therefore always attempt to insert a new record, resulting in a conflict with the uniqueness-constraint on the OneToOneField
.
这是原始问题的原因:
用户
实例,没有 id
。用户
实例, post_save
钩子创建一个新的配置文件
实例如前所述。个人资料
实例,没有 id
($自动添加 pk
字段)。个人资料
实例。 User
instance, with no id
.User
instance, the post_save
hook creating a new Profile
instance as before.Profile
instance, with no id
(the automatically added pk
field).Profile
instance.
pk
(在这种情况下 id
)是没有设置,Django尝试创建一个新的记录。用户
字段的表的唯一性约束的违反。pk
(in this case id
) is not set, Django attempts to create a new record.user
field.