﻿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
15200	"ManyToManyField combined with ""|"" leads to trouble"	Klaas van Schelven	nobody	"!ManyToManyField combined with ""|"" leads to trouble.

Specifically, the outer join that appears to be constructed for manytomany field lookups is not well cleaned up with where statements once an ""or"" (""|"") is used.

{{{
$ cat theapp/models.py
from django.db import models

class AnObject(models.Model):
    nr = models.IntegerField()

class HasRef(models.Model):
    obj = models.ManyToManyField(AnObject)
    field = models.IntegerField()
}}}

{{{
>>> from theapp.models import *
>>> one = AnObject.objects.create(nr=1)
>>> two = AnObject.objects.create(nr=2)
>>> reffer = HasRef.objects.create(field=1)
>>> reffer.obj.add(one)
>>> reffer.obj.add(two)
>>> HasRef.objects.all().filter(field=1)
[<HasRef: HasRef object>]
>>> HasRef.objects.all().filter(obj=one)
[<HasRef: HasRef object>]
>>> HasRef.objects.all().filter(models.Q(field=1) | models.Q(obj=one))
[<HasRef: HasRef object>, <HasRef: HasRef object>]
>>> [o.pk for o in HasRef.objects.all().filter(models.Q(field=1) | models.Q(obj=one))]
[1L, 1L]
}}}

I don't have the time right now to come up with tests proper, or a patch. The problem is real though...

My workaround:

{{{
>>> HasRef.objects.all().filter(models.Q(field=1) | models.Q(obj=one)).annotate(models.Count(""id""))
}}}

The generated query (without workaround)
{{{
>>> print HasRef.objects.all().filter(models.Q(field=1) | models.Q(obj=AnObject.objects.get(nr=1))).query
SELECT `theapp_hasref`.`id`, `theapp_hasref`.`field` FROM `theapp_hasref` LEFT OUTER JOIN `theapp_hasref_obj` ON (`theapp_hasref`.`id` = `theapp_hasref_obj`.`hasref_id`) WHERE (`theapp_hasref`.`field` = 1  OR `theapp_hasref_obj`.`anobject_id` = 1 )
}}}
{{{"		closed	Uncategorized	1.2		wontfix		Klaas van Schelven	Unreviewed	0	0	0	0	0	0
