与用户模型(django.contrib.auth)的OneToOne关系,没有级联删除

Jor*_*ter 6 django one-to-one django-authentication cascading-deletes

当删除发挥作用时,我对OneToOneField的工作方式感到有些困惑.我能找到的唯一准权威信息来自django-developers上的这个帖子:

我不知道你是否发现了这个,但是删除工作是朝着一个方向发展的,但不是你想要的方向.例如,使用您在另一条消息中发布的模型:

class Place(models.Model): 
    name = models.CharField(max_length = 100)  
class Restaurant(models.Model): 
    place = models.OneToOneField(Place, primary_key=True)  
Run Code Online (Sandbox Code Playgroud)

如果您创建了与其关联的地方和餐厅,则删除该餐厅将不会删除该地点(这是您在此处报告的问题),但删除该地点将删除该餐厅.

我有以下型号:

class Person(models.Model):
    name = models.CharField(max_length=50)
    # ... etc ...
    user = models.OneToOneField(User, related_name="person", null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

它的成立这种方式让我可以轻松地访问personUser使用实例user.person.

但是,当我尝试删除User管理员中的记录时,自然它会向后传递到我的Person模型,正如线程所讨论的那样,显示了以下内容:

您确定要删除用户"JordanReiter2"吗?以下所有相关项目将被删除:

  • 网友:JordanReiter
    • 人:JordanReiter
      • 提交:Title1
      • 提交:Title2

不用说,我也没有要删除的Person记录,或任何其后代!

我想我理解逻辑:因为Person记录中的OneToOne字段中有一个值,删除User记录会user_id在数据库的列中创建一个错误的引用.

通常,解决方案是切换OneToOne字段所在的位置.当然,这是不可能的,因为User对象几乎是由它设定的django.contrib.auth.

有没有办法防止删除级联,同时仍然有一个直接的方式来访问人user?是创建扩展版本的模型的唯一方法吗?Userdjango.contrib

更新

我改变了模型名称,所以希望它现在更清晰了.基本上,有成千上万的人事记录.不是每个人都有登录,但如果他们这样做,他们只有一个登录.

Jor*_*ter 23

原来,这两个ForeignKeyOneToOneField有一个属性on_delete,你可以设置为models.SET_NULL,就像这样:

class Person(models.Model):
    name = models.CharField(max_length=50)
    # ... etc ...
    user = models.OneToOneField(User, on_delete=models.SET_NULL, related_name="person", null=True, blank=True)
Run Code Online (Sandbox Code Playgroud)

这导致我想要的行为:User删除模型而不触及Person记录.我忽略了它,因为它没有明确列出OneToOneField,它简单地说

另外,OneToOneField接受ForeignKey接受的所有额外参数......

容易错过.