Sriram
Sriram

Reputation: 511

Django admin delete != Model.delete()

In our codebase, T which is a Model, has a foreign key dependency on a Model P (with on_delete=CASCADE), has a many-to-many field on Model C, and so on.

My support task is to delete all Ts whose p__name (p is the foreign key reference to P) belongs to a set of 500+ values.

I experimented with two approaches:
1. To log into the django admin portal and delete an individual instance of T from there.
2. I also tried to do the following t = T.objects.get(p__name="..some-name.."); t.delete()

Approach #1 seems to clean up all linkages. Where as approach #2 could not delete the model pointed to by t.p. Both the approaches hit the Model.delete() method and I have verified this. Yet, #1 is more effective than #2. However, #1 is manual and #2 is programmatic (and, therefore, desirable).

I am looking for a programmatic method which could replicate the delete action from admin site.

Solution - The programmatic way to delete Ts turned out to be delete Ps. I have accepted Alasdair's answer. I still have not found the reason behind the non-equivalence of #1 and #2. That is for some another day.

Upvotes: 0

Views: 345

Answers (1)

Alasdair
Alasdair

Reputation: 308829

I think you've misunderstood how cascade works. If I understand your question correctly, your models are something like:

class P(models.Model):
    pass

class T(models.Model):
    # on_delete=models.CASCADE is the default, including it here to be explicit
    p = models.ForeignKey(P, on_delete=models.CASCADE) 

Deleting a t will not cause the related p to be deleted. The CASCADE means that if you delete a p, then all t's that link to p will be deleted.

p = P.objects.get(name="x")
p.delete() # all t's that link to p will be deleted.

This is the case whether you use the Django admin or do it programmatically.

Upvotes: 1

Related Questions