0

Suppose I have an object called Person that has a foreign key that links to CLothes which links to

class Person(models.Model):
    clothes = models.ForeignKey('Clothes', on_delete=models.PROTECT)
    jokes = models.ManyToManyField(to='Jokes')

class Clothes(models.Model):
    fabric = models.ForeignKey('Material', on_delete=models.PROTECT)

class Material(models.Model):
    plant = models.ForeignKey('Plant', on_delete=models.PROTECT)

And if I wanted to delete person, I would have to delete Clothes, Jokes, Materials attached to it. Is there a way to recursively detect all the foreign keys so that I can delete them?

Minh
  • 2,180
  • 5
  • 23
  • 50

1 Answers1

2

The django.db.models.deletion.Collector is suited for this task. It is what Django uses under the hood to cascade deletions.

You can use it this way:

from django.db.models.deletion import Collector

collector = Collector(using='default')  # You may specify another database
collector.collect([some_instance])
for model, instance in collector.instances_with_model():
    # Our instance has already been deleted, trying again would result in an error
    if instance == some_instance:
        continue
    instance.delete()

For more information about the Collector class, you can refer to this question:

How to show related items using DeleteView in Django?

As mentioned in the comments, using on_delete=models.CASCADE would be the best solution but if you do not have control over that, this should work.

Community
  • 1
  • 1
aumo
  • 5,344
  • 22
  • 25