如何从子级级联删除到父级

1 投票
1 回答
983 浏览
提问于 2025-04-18 17:35

我有一个这样的模型:

class Todo(models.Model):
    user = models.OneToOneField(User)
    note = models.CharField(max_length=255)
    is_important = models.BooleanField(default=False)
    is_complete = models.BooleanField(default=False)
    reminder = models.OneToOneField(Reminder, blank=True, null=True, on_delete=models.SET_NULL)


class Reminder(models.Model):
    start_time = models.DateTimeField()
    stop_time = models.DateTimeField(blank=True)

简单来说,当提供了开始时间和可选的结束时间时,一个待办事项(Todo)就变成了一个提醒(Reminder)。

目前,当我删除一个提醒对象时,待办事项对象中的提醒字段会被设置为空(Null),这正是我想要的效果。

我想知道的是:

我该如何设置这些模型,以便如果一个待办事项对象被删除,相关的提醒对象也会被删除呢?

另外,如果这不是一对一的关系,比如说是多对一的关系(多个待办事项对应一个提醒),那么我该如何设置模型,以便如果一个待办事项被删除,提醒对象也会被删除,但前提是没有其他待办事项与这个提醒关联?

还有,关于:

stop_time = models.DateTimeField(blank=True)

如果在表单中留空,数据库中会存储什么默认值呢?

1 个回答

2

你正在定义一种关系,如下所示:

    reminder = models.OneToOneField(Reminder, blank=True, null=True,
                 on_delete=models.SET_NULL)

在这里,你指定了 on_delete=models.SET_NULL。这意味着当你删除一个被引用的对象时,Django会把这个字段的值设置为NULL(空值)。如果你想要在删除对象时也把这个字段的值删除,可以使用 models.CASCADE。Django默认就是用这个选项。

更多信息可以参考 这里

stop_time = models.DateTimeField(blank=True)

如果什么都不指定,这个字段就不会被设置,结果会是空白的,这里没有默认值。


正如评论中提到的,如果你想在删除 Reminder 对象时,把对应的 Todo 对象中的提醒字段设置为 NULL,那么你可以把 OneToOne 关系放在 Reminder 类中,而不是 Todo 类中。

由于这是一个一对一的关系,根据Django的ORM(对象关系映射),把它放在任意一个类中都是一样的。你可以通过这两个对象的属性来访问它。

对于多对一的关系,你需要使用前后删除信号。但信号也有它自己的限制。

撰写回答