【问题标题】:How to cascade delete from a child to a parent如何级联删除从孩子到父母
【发布时间】:2014-08-17 20:29:58
【问题描述】:

我有以下型号:

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)

基本上,当提供开始时间和可选结束时间时,待办事项会变成提醒。

目前,当我删除 Reminder 对象时,Todo 对象中的提醒字段设置为 Null,这是我想要的。

我需要知道的:

如何设置这些模型,以便在删除 Todo 对象时,相应的 Reminder 对象也将被删除?

另外,如果它不是一对一的关系,假设它是一个多对一(多个 Todo 对一个提醒)的关系,如何设置模型以便如果 Todo 对象是删除时,Reminder 对象也将被删除,但前提是没有更多的 Todo 对象链接到 Reminder?

另外,关于:

stop_time = models.DateTimeField(blank=True)

如果表单中留空,默认值是多少,存储在数据库中?

【问题讨论】:

    标签: python database django django-models


    【解决方案1】:

    您将关系定义为

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

    您在此处指定on_delete=models.SET_NULL。这告诉 django 在删除引用的对象时将该字段设置为 NULL。如果您也想删除该对象,请使用models.CASCADE。 Django 使用它作为默认值。

    更多参考here

    stop_time = models.DateTimeField(blank=True)
    

    当没有指定此字段时,不会设置此字段并将为空白,则此字段没有默认值。


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

    作为它的一对一关系,根据 django ORM,当您放入任何一个类时,它都是相同的。您将通过两个对象的属性访问它。

    对于多对一,您必须使用 pre-post 删除信号。但信号有其自身的局限性

    【讨论】:

    • 我不想使用到 models.CASCADE 因为当一个 Reminder 对象被删除时我想将相应的 Todo 对象中的提醒字段设置为 NULL,但是当一个 Todo 对象被删除时我想删除对应的 Reminder 对象。我如何设置我的模型来实现这一点?
    • @OliverFunk,在这种情况下,您可以在Reminder 类中设置onetoone 关系。对于多对一,您将不得不使用 pre-post delete 信号。但信号有其自身的局限性。
    • 但这似乎是 Reminder 对象中不必要的字段。我的意思是,关系已经在 Todo 对象中定义了,为什么我还要在 Reminder 对象中定义它呢?这也将在数据库中创建另一列,这似乎没有必要。我是否应该在 Todo 对象中创建一个方法,该方法在删除 Todo 时执行并删除与其关联的 Reminder 对象?
    • @OliverFunk,我建议将关系字段移动到Reminder 类。
    • 啊该死的!我误读了您的评论...您的建议完全有道理。您可以更改您的答案,以便我将其标记为正确吗?
    猜你喜欢
    • 2017-06-30
    • 1970-01-01
    • 2019-02-02
    • 2012-09-12
    • 2012-06-13
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多