On 5/9/2009 12:34 PM, Margie wrote: > I've had my share of confusion over delete. Here's a thread that I > had with Malcolm recently: > > http://groups.google.com/group/django-users/browse_thread/thread/582f21486c1073eb/7f5743953047d9fa?lnk=raot&fwc=1 > > However, I guess I'm still quite confused. One thing I don't > understand is when the "bulk delete" happens. I thought, for example, > that it happened when one uses the queryset delete. So I just wrote > myself a little test. > > Here's the model. I have a 'Book' and it has readers (that have > ForeignKey back to Book) > > class Publisher(models.Model): > name = models.CharField(max_length=100) > > class Book(models.Model): > title = models.CharField(max_length=100) > publisher = models.ForeignKey(Publisher, blank=True, null=True) > > class Reader(models.Model): > book = models.ForeignKey(Book, blank=True, null=True) > name = models.CharField(max_length=100) > > Here's a small snippet of code that creates a book with two readers. > I then delete the book using a queryset delete. I thought that in > this case neither Book.delete() nor Reader.delete() would get called. > However, the output indicates that preDeleteCallBack() does get > called, once for the deletion of book1, and once for each of the two > reader objects. > > def preDeleteCallBack(sender, instance=None, **kwargs): > print "PreDelete called for instance", instance > > pre_delete.connect(preDeleteCallBack, sender=Reader) > pre_delete.connect(preDeleteCallBack, sender=Book) > > pub1 = Publisher.objects.create(name="pub1") > book1 = Book.objects.create(title="book1", publisher=pub1) > reader1 = Reader.objects.create(name="reader1", book=book1) > reader2 = Reader.objects.create(name="reader2", book=book1) > > Book.objects.filter(title="book1").delete() > > The output from this call to delete() is: > > PreDelete called for instance book1 > PreDelete called for instance Reader object > PreDelete called for instance Reader object > > > In my app, I use a lot of formsets. I thought that bulk delete got > used for those. Yet again, when I tested it using a little debug app > I find that the preDeleteCallBack() function gets called. For > example: > > bookPostDict = { > 'form-INITIAL_FORMS': u'1', 'form-TOTAL_FORMS': u'1', 'form-0- > title': u'book1', 'form-0-DELETE': u'on', 'form-0-id': u'1', 'form-0- > publisher': u'1', > } > > bookFormSet = BookFormSet(data=bookPostDict) > if bookFormSet.is_valid(): > bookFormSet.save() > > When bookFormSet.save() gets executed, I get this output: > > PreDelete called for instance book1 > PreDelete called for instance Reader object > PreDelete called for instance Reader object > > So I guess I am totally confused now. I know I have had a ton of > problems with my foreignKey objects getting deleted when the thing > they point to gets deleted. Based on Malcolm's response in the thread > above, it certainly seemed like I was in bulk delete territory, but > using these pruned down examples I find I can't even get a bulk delete > to happen. > > George, would you be able to clarify when the bulk delete happens? I > see in the doc that it says: > > "Keep in mind that this will, whenever possible, be executed purely in > SQL, and so the delete() methods of individual object instances will > not necessarily be called during the process." > > Perhaps in my queryset delete I am not hitting the case where bulk > delete will be called? I am also interested particularly in formsets > and what happens when can_delete is True and what happens when the > delete occurs as a result of doing a formset save() when some objects > have been targeted for deletion. > > Sorry for the length of this. I've spent all morning trying to grock > this and am disappointed that my debugging work has resulted in me > being even more confused than before!
I haven't looked at the code so I can't comment on specifics. Keep in mind, however, that signals are sent independently of whether `Model.delete()` is invoked. I think if you want to know definitively if your `delete()` method is being called or not, your debug statement should go in that method. I wouldn't be surprised if Django is sending pre and post delete signals even during bulk deletion. -- George --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---