﻿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
14609	__or__ method of queries does not return a correctly combined query.	Stephen Burrows	nobody	"Unfortunately, I don't have enough experience in SQL or the internals of Django ORM to better pin down where exactly the problem is, but the symptom is as follows. Given the following code:
{{{
def get_view_forms(view, node):
	return get_entity_forms(view, passthrough=False) | get_entity_forms(node)
}}}

get_entity_forms returns a queryset. The particular issue I'm running across is that:
get_entity_forms(view, passthrough=False) returns []
get_entity_forms(node) returns [<Form 1>]
get_view_forms(view, node) returns [] when it ought to return [<Form 1>]

More generally, get_entity_forms(node) [i.e. ""other""] is being ignored altogether.

I'm not sure what the easiest way to reproduce this would be, other than pulling commit f90e2376351f29fd2ef7106484c72c9e1ab2186e from the bartleby branch of https://github.com/melinath/philo/ and making a basic deployment.

----

Complete code:
{{{
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from philo.contrib.bartleby.models import Form
from philo.models import Attribute, Entity


def get_entity_forms(entity, passthrough=True):
	if not isinstance(entity, Entity):
		raise TypeError
	
	if passthrough and entity.attributes.passthrough is not None:
		exclude_keys = [] # Exclude keys already found
		
		def get_attribute_forms(qs_mapper):
			qs = Form.objects.none()
			
			for attribute in qs_mapper.queryset.exclude(key__in=exclude_keys):
				fk_q = Q(foreignkeyvalue_set__attribute_set=attribute)
				m2m_q = Q(foreignkeyvalue_set__manytomanyvalue__attribute_set=attribute)
				
				qs |= Form.objects.filter(fk_q | m2m_q)
				exclude_keys.append(attribute.key)
			
			if qs_mapper.passthrough:
				qs |= get_attribute_forms(qs_mapper.passthrough)
			
			return qs
		
		return get_attribute_forms(entity.attributes).distinct()
	
	entity_ct = ContentType.objects.get_for_model(entity)
	
	fk_q = Q(foreignkeyvalue_set__attribute_set__entity_content_type=entity_ct) &\
		Q(foreignkeyvalue_set__attribute_set__entity_object_id=entity.pk)
	m2m_q = Q(foreignkeyvalue_set__manytomanyvalue__attribute_set__entity_content_type=entity_ct) &\
		Q(foreignkeyvalue_set__manytomanyvalue__attribute_set__entity_object_id=entity.pk)
	
	return Form.objects.filter(fk_q | m2m_q).distinct()


def get_view_forms(view, node):
	return get_entity_forms(view, passthrough=False) | get_entity_forms(node)
}}}

The sql generated by get_entity_forms(view, passthrough=False):
{{{
SELECT DISTINCT ""bartleby_form"".""id"", ""bartleby_form"".""title"", ""bartleby_form"".""slug"", ""bartleby_form"".""help_text"", ""bartleby_form"".""email_template_id"", 
""bartleby_form"".""email_from"", ""bartleby_form"".""save_to_database"", ""bartleby_form"".""record"", ""bartleby_form"".""login_required"", 
""bartleby_form"".""allow_changes"", ""bartleby_form"".""max_submissions"" FROM ""bartleby_form"" INNER JOIN ""philo_foreignkeyvalue"" ON (""bartleby_form"".""id"" = 
""philo_foreignkeyvalue"".""object_id"") LEFT OUTER JOIN ""philo_attribute"" ON (""philo_foreignkeyvalue"".""id"" = ""philo_attribute"".""value_object_id"") LEFT OUTER 
JOIN ""philo_manytomanyvalue_values"" ON (""philo_foreignkeyvalue"".""id"" = ""philo_manytomanyvalue_values"".""foreignkeyvalue_id"") LEFT OUTER JOIN 
""philo_manytomanyvalue"" ON (""philo_manytomanyvalue_values"".""manytomanyvalue_id"" = ""philo_manytomanyvalue"".""id"") LEFT OUTER JOIN ""philo_attribute"" T9 ON 
(""philo_manytomanyvalue"".""id"" = T9.""value_object_id"") LEFT OUTER JOIN ""philo_attribute"" T10 ON (T9.""id"" = T10.""id"") WHERE 
(((""philo_attribute"".""entity_content_type_id"" = 23 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND ""philo_attribute"".""value_content_type_id"" = 14 ) 
AND (""philo_attribute"".""entity_object_id"" = 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND ""philo_attribute"".""value_content_type_id"" = 14 )) OR 
((T10.""entity_content_type_id"" = 23 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND T10.""value_content_type_id"" = 15 ) AND (T10.""entity_object_id"" 
= 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND T10.""value_content_type_id"" = 15 ))) ORDER BY ""bartleby_form"".""id"" ASC
}}}

The sql generated by get_entity_forms(node):
{{{
SELECT DISTINCT ""bartleby_form"".""id"", ""bartleby_form"".""title"", ""bartleby_form"".""slug"", ""bartleby_form"".""help_text"", ""bartleby_form"".""email_template_id"", 
""bartleby_form"".""email_from"", ""bartleby_form"".""save_to_database"", ""bartleby_form"".""record"", ""bartleby_form"".""login_required"", 
""bartleby_form"".""allow_changes"", ""bartleby_form"".""max_submissions"" FROM ""bartleby_form"" INNER JOIN ""philo_foreignkeyvalue"" ON (""bartleby_form"".""id"" = 
""philo_foreignkeyvalue"".""object_id"") LEFT OUTER JOIN ""philo_attribute"" ON (""philo_foreignkeyvalue"".""id"" = ""philo_attribute"".""value_object_id"") LEFT OUTER 
JOIN ""philo_manytomanyvalue_values"" ON (""philo_foreignkeyvalue"".""id"" = ""philo_manytomanyvalue_values"".""foreignkeyvalue_id"") LEFT OUTER JOIN 
""philo_manytomanyvalue"" ON (""philo_manytomanyvalue_values"".""manytomanyvalue_id"" = ""philo_manytomanyvalue"".""id"") LEFT OUTER JOIN ""philo_attribute"" T9 ON 
(""philo_manytomanyvalue"".""id"" = T9.""value_object_id"") LEFT OUTER JOIN ""philo_attribute"" T10 ON (T9.""id"" = T10.""id"") WHERE 
(((""philo_attribute"".""entity_content_type_id"" = 19 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND ""philo_attribute"".""value_content_type_id"" = 14 ) 
AND (""philo_attribute"".""entity_object_id"" = 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND ""philo_attribute"".""value_content_type_id"" = 14 )) OR 
((T10.""entity_content_type_id"" = 19 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND T10.""value_content_type_id"" = 15 ) AND (T10.""entity_object_id"" 
= 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND T10.""value_content_type_id"" = 15 ))) ORDER BY ""bartleby_form"".""id"" ASC
}}}

The combined SQL:
{{{
SELECT DISTINCT ""bartleby_form"".""id"", ""bartleby_form"".""title"", ""bartleby_form"".""slug"", ""bartleby_form"".""help_text"", ""bartleby_form"".""email_template_id"", 
""bartleby_form"".""email_from"", ""bartleby_form"".""save_to_database"", ""bartleby_form"".""record"", ""bartleby_form"".""login_required"", 
""bartleby_form"".""allow_changes"", ""bartleby_form"".""max_submissions"" FROM ""bartleby_form"" INNER JOIN ""philo_foreignkeyvalue"" ON (""bartleby_form"".""id"" = 
""philo_foreignkeyvalue"".""object_id"") LEFT OUTER JOIN ""philo_attribute"" ON (""philo_foreignkeyvalue"".""id"" = ""philo_attribute"".""value_object_id"") LEFT OUTER 
JOIN ""philo_manytomanyvalue_values"" ON (""philo_foreignkeyvalue"".""id"" = ""philo_manytomanyvalue_values"".""foreignkeyvalue_id"") LEFT OUTER JOIN 
""philo_manytomanyvalue"" ON (""philo_manytomanyvalue_values"".""manytomanyvalue_id"" = ""philo_manytomanyvalue"".""id"") LEFT OUTER JOIN ""philo_attribute"" T9 ON 
(""philo_manytomanyvalue"".""id"" = T9.""value_object_id"") LEFT OUTER JOIN ""philo_attribute"" T10 ON (T9.""id"" = T10.""id"") LEFT OUTER JOIN ""philo_attribute"" T13 
ON (""philo_attribute"".""id"" = T13.""id"") WHERE ((((""philo_attribute"".""entity_content_type_id"" = 23 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND 
""philo_attribute"".""value_content_type_id"" = 14 ) AND (""philo_attribute"".""entity_object_id"" = 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND 
""philo_attribute"".""value_content_type_id"" = 14 )) OR ((T10.""entity_content_type_id"" = 23 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND 
T10.""value_content_type_id"" = 15 ) AND (T10.""entity_object_id"" = 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND T10.""value_content_type_id"" = 15 
))) OR (((""philo_attribute"".""entity_content_type_id"" = 19 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND ""philo_attribute"".""value_content_type_id"" 
= 14 ) AND (""philo_attribute"".""entity_object_id"" = 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND ""philo_attribute"".""value_content_type_id"" = 14 
)) OR ((T13.""entity_content_type_id"" = 19 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND T13.""value_content_type_id"" = 15 ) AND 
(T13.""entity_object_id"" = 1 AND ""philo_foreignkeyvalue"".""content_type_id"" = 33 AND T13.""value_content_type_id"" = 15 )))) ORDER BY ""bartleby_form"".""id"" ASC
}}}"	Bug	closed	Database layer (models, ORM)	1.2	Normal	fixed			Accepted	0	0	0	0	0	0
