我正在创建一个自定义注释系统,它可以使用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')
我的理解是,当注释附加到的模型被删除时,删除应该级联并删除注释。
不幸的是,这并没有发生,我被难住了。有没有什么常见的原因会改变默认的删除行为?
发布于 2011-07-24 04:49:41
不,文档上没有这么说。它说的是,如果你在一个模型上定义了一个GenericRelation
--即GenericForeignKey
的反面--那么当带有通用FK的项被删除时,带有GenericRelation的项也会被删除。
与ForeignKey不同,GenericForeignKey不接受on_delete参数来自定义此行为;如果需要,只需不使用GenericRelation即可避免级联删除,并可通过pre_delete信号提供替代行为。
发布于 2018-05-04 19:59:41
我意识到这是一个非常的老问题,所以事情可能与被问到这个问题时不同,但今天早上被接受的答案让我陷入了困境,因此我想把这个留在这里,以防后代分享我的痛苦。
从文档中:
还请注意,如果您删除一个具有GenericRelation的对象,则任何具有指向它的GenericForeignKey的对象也将被删除。在上面的例子中,这意味着如果一个书签对象被删除,任何指向它的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)
在上面的例子中,如果您的Comment对象有一个指向Post对象的通用外键,那么当Post对象被删除时,指向它的任何Comment对象也将被删除。
这是预期的行为,其操作方式与正常的ForeignKey相同。使用上面的相同示例,如果删除了Comment对象所指向的User对象,那么Comment也将被删除。
如果你碰巧遇到这个问题,因为你需要相反的行为,即当你删除评论时,帖子也会被删除,那么你可能需要使用signals的力量。
发布于 2018-08-10 17:30:22
除了前面的答案-如果你有更复杂的结构和类似GenericOneToOne
的东西(这在Django中不是直接存在的):
class Post(models.Model)
title = models.CharField(max_length=100)
class Comment(models.Model):
post = models.ForeignKey(Post)
body = models.TextField(verbose_name='Comment')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
class Meta:
# Constrain equals to OneToOne relation.
unique_together = ('content_type', 'object_id')
class Author(models.Model):
comment = GenericRelation(Comment)
name = models.CharField(max_length=100)
如果你想删除Post
,并确保Comment
和Author
也被删除,你需要编写定制的post_delete
信号:
from django.db.models.signals import post_delete
from django.dispatch import receiver
@receiver(post_delete, sender=Comment, dispatch_uid='delete_comment_content_object')
def delete_comment_content_object(sender, instance, using, **kwargs):
instance.content_object.delete()
如果像这样覆盖Comment
类delete
方法:
def delete(self, *args, **kwargs):
self.content_object.delete()
super().delete(args, kwargs)
如果您删除,它将删除Author
only。如果删除Post
,Author
对象将保留在数据库中。
https://stackoverflow.com/questions/6803018
复制相似问题