删除时为什么我的GenericForeignKey级联不会?

Sov*_*iut 20 django foreign-keys cascading-deletes django-contenttypes generic-foreign-key

我正在创建一个自定义评论系统,可以使用contenttypes GenericForeignKey将评论附加到任何模型.

class Comment(models.Model):
    body = models.TextField(verbose_name='Comment')
    user = models.ForeignKey(User)
    parent = models.ForeignKey('self', null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
Run Code Online (Sandbox Code Playgroud)

我的理解是,当附加注释的模型被删除时,删除应该级联并删除注释.

不幸的是,这没有发生,我很难过.是否有任何常见原因可以更改默认删除行为?

Dan*_*man 29

不,文档没有说明.它说的是,如果你GenericRelation在模型上定义一个- 即反面GenericForeignKey- 那么当删除具有通用FK的项目时,也会删除带有GenericRelation的项目.

与ForeignKey不同,GenericForeignKey不接受on_delete参数来自定义此行为; 如果需要,您可以通过不使用GenericRelation来避免级联删除,并且可以通过pre_delete信号提供备用行为.

  • 我认为 django 文档应该反过来说明这一点。“GenericForeignKey 不会级联删除,而是将值设置为 null。仅当相关模型中使用 GenericRelation 时,它才会级联。”。这是必需的,因为我们在普通外键中默认会进行级联删除。 (4认同)

小智 6

我意识到这是一个非常老的问题,因此可能与提出该问题时有所不同,但是今天早晨我接受了一个兔子洞的钻探,因此我希望将此问题留在这里,以防止子孙后代分担痛苦。

从文档:

还要注意,如果删除具有GenericRelation的对象,则任何具有GenericForeignKey指向该对象的对象也将被删除。在上面的示例中,这意味着如果删除了Bookmark对象,则指向该对象的所有TaggedItem对象都将被同时删除。

这与公认的答案相反。想象以下情况:

class Comment(models.Model):
    body = models.TextField(verbose_name='Comment')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

class Post(models.Model):
    comment = GenericRelation(Comment)
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,如果Comment对象具有指向Post对象的通用外键,则删除Post对象时,指向该对象的所有Comment对象也将被删除。

这是预期的行为,其操作与普通的ForeignKey相同。使用上面相同的示例,如果Comment对象指向的User对象被删除,则Comment也将被删除。

如果您碰巧遇到此问题是因为您需要与此行为相反,即,当您删除注释时,帖子也会被删除,那么您可能将需要使用信号的力量。