Penso che tu abbia capito bene con i soldi, tranne che non hai bisogno di convertirli in una lista.
source.items.remove(*source.items.filter(*args))
Il metodo remove
/add
si presenta come il seguente
remove(self, *objs)
add(self, *objs)
e la documentazione http://www.djangoproject.com/documentation/models/many_to_many/ uso aggiungere più esempi sotto forma di [p1, p2, p3]
quindi scommetto lo stesso vale per remove
, visto che gli argomenti sono gli stessi.
>>> a2.publications.add(p1, p2, p3)
Scavando in un po 'di più, i itera funzione Remove oltre *objs
uno per uno, controllando se è del modello valido, altrimenti utilizzando i valori come PK, quindi elimina le voci con un pk__in
, quindi sono dirò di si, il modo migliore è di interrogare prima la tabella m2m per gli oggetti da eliminare e poi passare quegli oggetti nel manager m2m.
# django.db.models.related.py
def _remove_items(self, source_field_name, target_field_name, *objs):
# source_col_name: the PK colname in join_table for the source object
# target_col_name: the PK colname in join_table for the target object
# *objs - objects to remove
# If there aren't any objects, there is nothing to do.
if objs:
# Check that all the objects are of the right type
old_ids = set()
for obj in objs:
if isinstance(obj, self.model):
old_ids.add(obj.pk)
else:
old_ids.add(obj)
if self.reverse or source_field_name == self.source_field_name:
# Don't send the signal when we are deleting the
# duplicate data row for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action="pre_remove",
instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=old_ids)
# Remove the specified objects from the join table
db = router.db_for_write(self.through.__class__, instance=self.instance)
self.through._default_manager.using(db).filter(**{
source_field_name: self._pk_val,
'%s__in' % target_field_name: old_ids
}).delete()
if self.reverse or source_field_name == self.source_field_name:
# Don't send the signal when we are deleting the
# duplicate data row for symmetrical reverse entries.
signals.m2m_changed.send(sender=rel.through, action="post_remove",
instance=self.instance, reverse=self.reverse,
model=self.model, pk_set=old_ids)
Grazie! Ci proverò e vedrò come funziona. In questo momento sto usando una singola istruzione SQL raw (usando "DELETE ... USING" in PostgreSQL, che capisco non è standard). – bunnyhero
Sì, la maggior parte delle persone preferisce attenersi all'ORM :) –