magic-removal: Fixed #1372 -- Got many-to-many fields working in manipulators

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2374 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-02-23 20:10:41 +00:00
parent 208ea7bacb
commit f252b11a9c
2 changed files with 14 additions and 11 deletions

View File

@ -210,7 +210,7 @@ class ManyRelatedObjectsDescriptor(object):
class RelatedManager(superclass): class RelatedManager(superclass):
def get_query_set(self): def get_query_set(self):
return superclass.get_query_set(self).filter(**(self.core_filters)) return superclass.get_query_set(self).filter(**(self.core_filters))
if rel_type == "o2m": if rel_type == "o2m":
def add(self, **kwargs): def add(self, **kwargs):
kwargs.update({rel_field.name: instance}) kwargs.update({rel_field.name: instance})
@ -471,20 +471,20 @@ class ManyToManyField(RelatedField, Field):
def _get_m2m_column_name(self, related): def _get_m2m_column_name(self, related):
"Function that can be curried to provide the source column name for the m2m table" "Function that can be curried to provide the source column name for the m2m table"
return related.model._meta.object_name.lower() + '_id' return related.model._meta.object_name.lower() + '_id'
def _get_m2m_reverse_name(self, related): def _get_m2m_reverse_name(self, related):
"Function that can be curried to provide the related column name for the m2m table" "Function that can be curried to provide the related column name for the m2m table"
return related.parent_model._meta.object_name.lower() + '_id' return related.parent_model._meta.object_name.lower() + '_id'
def isValidIDList(self, field_data, all_data): def isValidIDList(self, field_data, all_data):
"Validates that the value is a valid list of foreign keys" "Validates that the value is a valid list of foreign keys"
mod = self.rel.to._meta.get_model_module() mod = self.rel.to
try: try:
pks = map(int, field_data.split(',')) pks = map(int, field_data.split(','))
except ValueError: except ValueError:
# the CommaSeparatedIntegerField validator will catch this error # the CommaSeparatedIntegerField validator will catch this error
return return
objects = mod.get_in_bulk(pks) objects = mod._default_manager.in_bulk(pks)
if len(objects) != len(pks): if len(objects) != len(pks):
badkeys = [k for k in pks if k not in objects] 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.", 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) super(ManyToManyField, self).contribute_to_class(cls, name)
# Add the descriptor for the m2m relation # Add the descriptor for the m2m relation
setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self)) setattr(cls, self.name, ReverseManyRelatedObjectsDescriptor(self))
# Set up the accessor for the m2m table name for the relation # Set up the accessor for the m2m table name for the relation
self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta) self.m2m_db_table = curry(self._get_m2m_db_table, cls._meta)
def contribute_to_related_class(self, cls, related): def contribute_to_related_class(self, cls, related):
setattr(cls, related.get_accessor_name(), ManyRelatedObjectsDescriptor(related, 'm2m')) setattr(cls, related.get_accessor_name(), ManyRelatedObjectsDescriptor(related, 'm2m'))
# Add the descriptor for the m2m relation # 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 # 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_column_name = curry(self._get_m2m_column_name, related)
self.m2m_reverse_name = curry(self._get_m2m_reverse_name, related) self.m2m_reverse_name = curry(self._get_m2m_reverse_name, related)
def set_attributes_from_rel(self): def set_attributes_from_rel(self):
pass pass

View File

@ -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)): 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) 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: for f in self.opts.many_to_many:
if self.follow.get(f.name, None): if self.follow.get(f.name, None):
if not f.rel.edit_inline: if not f.rel.edit_inline:
@ -120,9 +120,12 @@ class AutomaticManipulator(forms.Manipulator):
new_vals = new_data.get(f.name, ()) new_vals = new_data.get(f.name, ())
else: else:
new_vals = new_data.getlist(f.name) new_vals = new_data.getlist(f.name)
was_changed = getattr(new_object, 'set_%s' % f.name)(new_vals) # First, clear the existing values.
if self.change and was_changed: rel_manager = getattr(new_object, f.name)
self.fields_changed.append(f.verbose_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)) expanded_data = DotExpandedDict(dict(new_data))
# Save many-to-one objects. Example: Add the Choice objects for a Poll. # Save many-to-one objects. Example: Add the Choice objects for a Poll.