...
>> I would have expected something along the lines of :
>>
>> DELETE FROM `api_voter_districts` WHERE `voter_id` = 1
>>
>> But instead it's 2 queries:
>>
>> SELECT `api_voter_districts`.`id`, `api_voter_districts`.`voter_id`,
>> `api_voter_districts`.`district_id` FROM `api_voter_districts` WHERE
>> `api_voter_districts`.`voter_id` = 1
>>
>> DELETE FROM `api_voter_districts` WHERE `id` IN (2, 3, 4, 5, 6,...)
...
> To me it seems there is no reason to do two queries in delete if the
> following conditions hold:
> - there are no signals sent for the deleted objects
> - the delete does not cascade further (actually you don't need to
> collect even in this case - you can do the cascade query completely in
> the DB without fetching the IDs first).
>
> For automatic M2M tables the above conditions always hold, but it is
> not guaranteed if you are using the "through" argument.
Ah, yes, hmm. Actually, it *is* possible to get signals attached to
the through.
from django.db.models import signals
signals.pre_delete.connect(handler, sender=Voter.districts.through)
So I don't think we can even take that shortcut on just the auto m2m
tables. As the "signals maintainer", let me just say: damn, they
cause a lot of trouble. :-)
OK, it would be easy enough to add a signal method to see if there are
signals attached for a given sender (model in this case).
I'll work up a patch for the simplified case of auto-intermediates and
no receivers for pre/post delete and see where that gets us in
performance.
Do we already have machinery in place for "does this model have the
potential to cascade"? I see Collector uses
._meta.get_all_related_objects, but that seems pretty heavy for the
simple need to branch depending on "yes or no".