diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 0e1addf1a46..0677f2cda02 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -710,7 +710,7 @@ class ReverseManyRelatedObjectsDescriptor(object): model=rel_model, core_filters={'%s__pk' % self.field.related_query_name(): instance._get_pk_val()}, instance=instance, - symmetrical=(self.field.rel.symmetrical and isinstance(instance, rel_model)), + symmetrical=self.field.rel.symmetrical, source_field_name=self.field.m2m_field_name(), target_field_name=self.field.m2m_reverse_field_name(), reverse=False @@ -991,7 +991,7 @@ class ManyToManyField(RelatedField, Field): kwargs['rel'] = ManyToManyRel(to, related_name=kwargs.pop('related_name', None), limit_choices_to=kwargs.pop('limit_choices_to', None), - symmetrical=kwargs.pop('symmetrical', True), + symmetrical=kwargs.pop('symmetrical', to==RECURSIVE_RELATIONSHIP_CONSTANT), through=kwargs.pop('through', None)) self.db_table = kwargs.pop('db_table', None) diff --git a/tests/regressiontests/m2m_regress/models.py b/tests/regressiontests/m2m_regress/models.py index 7f6da3341be..5453d396ae2 100644 --- a/tests/regressiontests/m2m_regress/models.py +++ b/tests/regressiontests/m2m_regress/models.py @@ -17,6 +17,13 @@ class Tag(models.Model): def __unicode__(self): return self.name +# Regression for #11956 -- a many to many to the base class +class TagCollection(Tag): + tags = models.ManyToManyField(Tag, related_name='tag_collections') + + def __unicode__(self): + return self.name + # A related_name is required on one of the ManyToManyField entries here because # they are both addressable as reverse relations from Tag. class Entry(models.Model): @@ -102,5 +109,17 @@ FieldError: Cannot resolve keyword 'porcupine' into field. Choices are: id, name >>> w.save() >>> w.delete() +# Regression for #11956 -- You can add an object to a m2m with the +# base class without causing integrity errors +>>> c1 = TagCollection.objects.create(name='c1') +>>> c1.tags = [t1,t2] + +>>> c1 = TagCollection.objects.get(name='c1') +>>> c1.tags.all() +[, ] + +>>> t1.tag_collections.all() +[] + """ }