Django中当子对象被删除时删除父对象

3
class A(models.Model):
    name = models.CharField(max_length=128)

class B(modes.Model):
    type_b = models.ForeignKey(A)

在Django的一对多关系中,当我删除相关的“多”对象(模型'B')之一时,如何删除“一”对象(模型'A')? 我通过Django管理批量删除选项删除模型'B'对象。

但我认为您必须将 "on_delete=models.CASCADE" 添加到ForeignKey字段,然后您可以删除A(models),这将自动删除B(models)。 - Davit Tovmasyan
3个回答

3
你应该使用 信号
@receiver(post_delete, sender=B)
def delete_a(sender, instance, **kwargs):
     # instance.type_b is the object which you want to delete

当我尝试使用 instance.type_b.delete() 进行删除时,我会收到 'NoneType' object has no attribute 'delete' 错误。 - albin antony
@albinantony 这样做:A.objects.filter(pk=instance.type_b.pk).delete() - Davit Tovmasyan
如果用户只有子模型的权限而没有父模型的权限,那么post_delete信号是否能够同时删除两个模型?@DavitTovmasyan - dsax7
@filtfilt 你会得到一个错误,你应该添加一个检查。 - Davit Tovmasyan

2
最佳实践是添加[on_delete=models.CASCADE][1]
class A(models.Model):
    name = models.CharField(max_length=128)

class B(modes.Model):
    type_b = models.ForeignKey(A,on_delete=models.CASCADE)

我已经尝试过 models.CASCADE 但它并没有按预期工作。 - albin antony
正如Davit Tovmasyan所说,尝试使用SIGNAL post_delete。 - Lemayzeur

0

你可以像Davit Tovmasyan建议的那样使用post_delete信号来删除父对象。

但是由于级联性质,当删除父对象A时,它也会删除所有连接的B对象,这将反过来在B模型上发出post_delete信号。因此,在第二次发出post_delete时,信号处理程序尝试删除已经删除的项目,导致'NoneType' object has no attribute 'delete'。你可以使用异常处理程序或者只是使用if条件来处理这个问题。

def delete_parent(sender, instance, **kwargs):
    if instance.type_b:
        instance.type_b.delete()

post_delete.connect(delete_parent, sender=B)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接