﻿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
25545	The ORM generates incorrect queries for m2m with disabled backward relations	Morgan Aubert	nobody	"This bug appears on the latest Django 1.8.5 release if you set two ManyToMany fields with the same name on two distinct models. The ManyToMany relations must be pointing toward the same model.

{{{
#!python
from django.db import models


class TestLabel(models.Model):
    label = models.CharField(max_length=100)


class TestModelA(models.Model):
    labels = models.ManyToManyField(TestLabel, related_name='a_labels+')


class TestModelB(models.Model):
    labels = models.ManyToManyField(TestLabel, related_name='b_labels+')

}}}

Whan you add a TestLabel instance to one of the ''labels'' relations, it is correctly added but you cannot fetch it using the all() method of the ManyRelatedManager: an empty list is returned.


{{{
>>> t1 = TestLabel.objects.create(label='Test 1')
>>> t2 = TestLabel.objects.create(label='Test 2')
>>> 
>>> a = TestModelA.objects.create()
>>> b = TestModelB.objects.create()
>>> 
>>> a.labels.add(t1)
>>> a.labels.all()
[]
}}}

Moreover, the generated SQL query is incorrect :

{{{
>>> print(a.labels.all().query)
SELECT ""example_project_testlabel"".""id"", ""example_project_testlabel"".""label"" FROM ""example_project_testlabel"" INNER JOIN ""example_project_testmodelb_labels"" ON ( ""example_project_testlabel"".""id"" = ""example_project_testmodelb_labels"".""testlabel_id"" ) WHERE ""example_project_testmodelb_labels"".""testmodelb_id"" = 4
}}}

The bug seems to be caused by the related_name which is generated when the backward relation is disabled (0e2d3b93043676975aa921a70b5faafef02cac5c). The related_name should be generated from the name of the relation and the name of the class (this add been fixed in Django 1.9 - see f7b297815819153b53dc1125d3f42869fb1b7ebc).

This bug can cause ValueError exceptions to be raised if prefetch_related is applied to a queryset :


{{{
>>> TestModelA.objects.all().prefetch_related('labels')
[...]
ValueError: Cannot query ""TestModelA object"": Must be ""TestModelB"" instance.
}}}
"	Bug	closed	Database layer (models, ORM)	1.8	Normal	duplicate	m2m, related_name		Unreviewed	0	0	0	0	0	0
