使用以下相关模型(一个博客条目可以有多个修订版):
class BlogEntryRevision(models.Model):
revisionNumber = models.IntegerField()
title = models.CharField(max_length = 120)
text = models.TextField()
[...]
class BlogEntry(models.Model):
revisions = models.ManyToManyField(BlogEntryRevision)
[...]
如何在删除相应的BlogEntryRevision
时告诉Django删除所有相关的BlogEntry
?如果删除了“其他”端的对象,则默认似乎是将对象保持为多对多关系。有没有办法做到这一点 - 最好不要覆盖BlogEntry.delete
?
答案 0 :(得分:13)
我认为你误解了ManyToMany关系的本质。你谈到被删除的“相应的BlogEntry”。但是,ManyToMany的重点在于每个BlogEntryRevision都有多个与其相关的 BlogEntries。 (当然,每个BlogEntry都有多个BlogEntryRevisions,但你已经知道了。)
从您使用的名称,以及您希望删除级联功能的事实来看,我认为使用BlogEntryRevision到BlogEntry的标准ForeignKey会更好。只要您没有在该ForeignKey上设置null=True
,删除就会被删除 - 当删除BlogEntry时,所有修订也都是。
答案 1 :(得分:10)
我今天有这个确切的用例:
为此,我使用了ManyToManyRelationship。
我的用例是:如果删除特定作者的最后一个条目,那么也应该删除该作者。
可以使用pre_delete
signal:
@receiver(pre_delete, sender=Entry)
def pre_delete_story(sender, instance, **kwargs):
for author in instance.authors.all():
if author.entries.count() == 1 and instance in author.entries.all():
# instance is the only Entry authored by this Author, so delete it
author.delete()
答案 2 :(得分:2)
您可以使用custom model manager,但文档似乎表明does do something like this already并且我无法回想起这意味着什么:
删除方法很方便 命名为delete()。这种方法 立即删除对象并具有 没有回报价值。例如:
e.delete()
您也可以删除对象 散装。每个QuerySet都有一个delete() 方法,删除所有成员 那个QuerySet。
例如,这会删除所有条目 pub_date年份为2005年的对象:
Entry.objects.filter(pub_date__year=2005).delete()
请记住,无论何时,这都会 可能,纯粹用SQL执行, 所以delete()方法 单个对象实例不会 必然会被称为 处理。如果您提供了自定义 模型类的delete()方法和 想要确保它被调用,你 将需要“手动”删除 该模型的实例(例如,通过 迭代QuerySet并调用 单独删除每个对象上的() 而不是使用批量删除() QuerySet的方法。
当Django删除一个对象时,它 模拟SQL的行为 约束ON DELETE CASCADE - in 换句话说,任何具有的对象 指向对象的外键 被删除将被删除 它。例如:
b = Blog.objects.get(pk=1) # This will delete the Blog and all of its Entry objects. b.delete()
答案 3 :(得分:1)
只需使用clear()
方法删除相关对象,因为Django使用直通模型来指定clear方法删除所有相关BlogEntryRevision
be = BlogEntry.objects.get(id=1)
be.blogentryrevision_set.clear()