From 64a2718f6c7d0c434478b8a09a142d925a0741b3 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Wed, 20 Dec 2006 14:06:27 +0000 Subject: [PATCH] Refactored workhorse methods on m2m descriptors. Modified _add to check for the type of incoming objects (to match existing _remove implementation), and modified _remove to use a single query rather than 1 per object (to match existing _add implementation). git-svn-id: http://code.djangoproject.com/svn/django/trunk@4233 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/fields/related.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 08f110b6a6..797ef05be1 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -319,6 +319,10 @@ def create_many_related_manager(superclass): # If there aren't any objects, there is nothing to do. if objs: + # Check that all the objects are of the right type + for obj in objs: + if not isinstance(obj, self.model): + raise ValueError, "objects to add() must be %s instances" % self.model._meta.object_name # Add the newly created or already existing objects to the join table. # First find out which items are already added, to avoid adding them twice new_ids = set([obj._get_pk_val() for obj in objs]) @@ -345,16 +349,20 @@ def create_many_related_manager(superclass): # *objs - objects to remove from django.db import connection - for obj in objs: - if not isinstance(obj, self.model): - raise ValueError, "objects to remove() must be %s instances" % self.model._meta.object_name - # Remove the specified objects from the join table - cursor = connection.cursor() - for obj in objs: - cursor.execute("DELETE FROM %s WHERE %s = %%s AND %s = %%s" % \ - (self.join_table, source_col_name, target_col_name), - [self._pk_val, obj._get_pk_val()]) - transaction.commit_unless_managed() + # If there aren't any objects, there is nothing to do. + if objs: + # Check that all the objects are of the right type + for obj in objs: + if not isinstance(obj, self.model): + raise ValueError, "objects to remove() must be %s instances" % self.model._meta.object_name + # Remove the specified objects from the join table + old_ids = set([obj._get_pk_val() for obj in objs]) + cursor = connection.cursor() + cursor.execute("DELETE FROM %s WHERE %s = %%s AND %s IN (%s)" % \ + (self.join_table, source_col_name, + target_col_name, ",".join(['%s'] * len(old_ids))), + [self._pk_val] + list(old_ids)) + transaction.commit_unless_managed() def _clear_items(self, source_col_name): # source_col_name: the PK colname in join_table for the source object