id summary reporter owner description type status component version severity resolution keywords cc stage has_patch needs_docs needs_tests needs_better_patch easy ui_ux 11956 ReverseManyRelatedObjectsDescriptor wrongly assumes symmetry between inherited objects Nicolas Dietrich malcalypse "Symmetrical many-to-many do only make sense between objects of the same model type, as described in the documentation. However, ''!ReverseManyRelatedObjectDescriptors'' wrongly assume symmetricity when defining a ''!ManyToManyField'' from an inherited model towards a base class, as in the following model definition: {{{ class BaseModel(models.Model): pass class ChildModel(BaseModel): many = models.ManyToManyField(BaseModel, related_name='many_children') }}} This results in the following integrity error in case Postgres is used (- for some reason, the problem does not occur using sqlite!): {{{ > from symmetricbug.models import * > base = BaseModel.objects.create() > child = ChildModel.objects.create() > child.many.add(base) [...] /usr/lib64/python2.5/site-packages/django/db/models/fields/related.pyc in add(self, *objs) 432 # If this is a symmetrical m2m relation to self, add the mirror entry in the m2m table 433 if self.symmetrical: --> 434 self._add_items(self.target_col_name, self.source_col_name, *objs) 435 add.alters_data = True [...] IntegrityError: insert or update on table ""symmetricbug_childmodel_many"" violates foreign key constraint ""symmetricbug_childmodel_many_childmodel_id_fkey"" DETAIL: Key (childmodel_id)=(1) is not present in table ""symmetricbug_childmodel"". }}} This obviously does not make any sense, because there is no ''!ChildModel'' object with id 1. The reason is that ''!ReverseManyRelatedObjectsDescriptor'' wrongly assumes symmetricity: `django.db.models.fields.related:609` is {{{ symmetrical=(self.field.rel.symmetrical and isinstance(instance, rel_model)), }}} and should be something alike {{{ symmetrical=(self.field.rel.symmetrical and instance.__class__ == rel_model.__class__), }}} to be aware of subclasses. '''Workaround''': Use ''symmetrical=False'' in the model definition: {{{ class ChildModel(BaseModel): many = models.ManyToManyField(BaseModel, related_name='many_children', symmetrical=False) }}}" closed Database layer (models, ORM) 1.1 fixed Accepted 0 0 0 0 0 0