Opened 8 years ago

Closed 8 years ago

#10304 closed (invalid)

topics/db/queries.txt about delete() lies!

Reported by: Marc Fargas Owned by: nobody
Component: Database layer (models, ORM) Version: 1.0
Severity: Keywords: delete
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


queries.txt 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.

Given how delete() is implemented in QuerySet one would say it's almost impossible to avoid calling the delete() of every object (to not say it does lots of things).

Option a would be to fix the docs, but current behaviour makes it almost impossible to delete large querysets without recurring to manual SQL (And dealing with QS cache, etc later). So this may have to be fixed in some way, or a workaround documented.

Change History (1)

comment:1 Changed 8 years ago by Karen Tracey

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Resolution: invalid
Status: newclosed

I haven't looked at the QuerySet code but a little shell experimentation shows that it is not impossible to avoid calling delete() of every single object. Given this model:

class DT(models.Model):
    name = models.CharField(max_length=5)

    def delete(self):
        print 'Delete for %s called' %
        super(DT, self).delete()

    def __unicode__(self):

and this shell session:

Python 2.5.1 (r251:54863, Jul 31 2008, 23:17:40) 
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.get_version()
u'1.1 pre-alpha SVN-9841'
>>> from ttt.models import DT
>>> DT.objects.create(name='x')
<DT: x>
>>> DT.objects.create(name='y')
<DT: y>
>>> DT.objects.create(name='z')
<DT: z>
>>> DT.objects.all()
[<DT: x>, <DT: y>, <DT: z>]
>>> x = DT.objects.all()[0]
>>> x.delete()
Delete for x called
>>> DT.objects.all()
[<DT: y>, <DT: z>]
>>> DT.objects.all().delete()
>>> DT.objects.all()

The individual delete() method was not called for DT.objects.all().delete().

(Even if it was the case that the code as written now always guaranteed the individual delete() methods were called, the doc would not be wrong. It is warning that the individual delete() may not be called when objects are deleted in bulk, it doesn't say it absolutely will not be called.)

Note: See TracTickets for help on using tickets.
Back to Top