diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index efaa4cf75e..28f4d97b93 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -210,7 +210,7 @@ class ManyRelatedObjectsDescriptor(object): class RelatedManager(superclass): def get_query_set(self): return superclass.get_query_set(self).filter(**(self.core_filters)) - + if rel_type == "o2m": def add(self, **kwargs): kwargs.update({rel_field.name: instance}) @@ -471,20 +471,20 @@ class ManyToManyField(RelatedField, Field): def _get_m2m_column_name(self, related): "Function that can be curried to provide the source column name for the m2m table" return related.model._meta.object_name.lower() + '_id' - + def _get_m2m_reverse_name(self, related): "Function that can be curried to provide the related column name for the m2m table" return related.parent_model._meta.object_name.lower() + '_id' def isValidIDList(self, field_data, all_data): "Validates that the value is a valid list of foreign keys" - mod = self.rel.to._meta.get_model_module() + mod = self.rel.to try: pks = map(int, field_data.split(',')) except ValueError: # the CommaSeparatedIntegerField validator will catch this error return - objects = mod.get_in_bulk(pks) + objects = mod._default_manager.in_bulk(pks) if len(objects) != len(pks): badkeys = [k for k in pks if k not in objects] raise validators.ValidationError, ngettext("Please enter valid %(self)s IDs. The value %(value)r is invalid.", @@ -514,10 +514,10 @@ class ManyToManyField(RelatedField, Field): super(ManyToManyField, self).contribute_to_class(cls, name) # Add the descriptor for the m2m relation setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self)) - + # Set up the accessor for the m2m table name for the relation self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta) - + def contribute_to_related_class(self, cls, related): setattr(cls, related.get_accessor_name(), ManyRelatedObjectsDescriptor(related, 'm2m')) # Add the descriptor for the m2m relation @@ -526,7 +526,7 @@ class ManyToManyField(RelatedField, Field): # Set up the accessors for the column names on the m2m table self.m2m_column_name = curry(self._get_m2m_column_name, related) self.m2m_reverse_name = curry(self._get_m2m_reverse_name, related) - + def set_attributes_from_rel(self): pass diff --git a/django/db/models/manipulators.py b/django/db/models/manipulators.py index f61db8560d..7932ccc694 100644 --- a/django/db/models/manipulators.py +++ b/django/db/models/manipulators.py @@ -112,7 +112,7 @@ class AutomaticManipulator(forms.Manipulator): if not f.primary_key and str(getattr(self.original_object, f.attname)) != str(getattr(new_object, f.attname)): self.fields_changed.append(f.verbose_name) - # Save many-to-many objects. Example: Poll.set_sites() + # Save many-to-many objects. Example: Set sites for a poll. for f in self.opts.many_to_many: if self.follow.get(f.name, None): if not f.rel.edit_inline: @@ -120,9 +120,12 @@ class AutomaticManipulator(forms.Manipulator): new_vals = new_data.get(f.name, ()) else: new_vals = new_data.getlist(f.name) - was_changed = getattr(new_object, 'set_%s' % f.name)(new_vals) - if self.change and was_changed: - self.fields_changed.append(f.verbose_name) + # First, clear the existing values. + rel_manager = getattr(new_object, f.name) + rel_manager.clear() + # Then, set the new values. + for n in new_vals: + rel_manager.add(f.rel.to._default_manager.get(pk=n)) expanded_data = DotExpandedDict(dict(new_data)) # Save many-to-one objects. Example: Add the Choice objects for a Poll.