﻿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
28657	Strangely odd behaviour when ordering QuerySet by BooleanField.	Leonardo Arroyo	nobody	"I have recently encountered problems with duplicated results in pagination and trying to pin down the problem this seems to be a problem in the Django queryset. I'll attempt to explain the problem. Take a look at the following Queryset:


{{{
>>> p = Project.objects.all().order_by(""closed"")
>>> p
<QuerySet [<Project: Campanha de Incentivo - Alimentando a Solidariedade (Outubro)>, <Project: Campanha de Incentivo - Projeto Fora das 4 Paredes>, <Project: projeto luciele>, <Project: Campanha de Incentivo - Menos é Mais>, <Project: Campanha de Incentivo - Projeto Conviver>, <Project: Campanha de Incentivo - Aula de Música>, <Project: RPINCLUSÃO - Informações, Acessibilidade e Inclusão>, <Project: Ong ong>, <Project: Campanha de Incentivo - Projeto Alimentando Vidas>, <Project: Bola na Rede>, <Project: Campanha de Incentivo - Projeto Bolas de Pelos>, <Project: Mãos Solidárias>, <Project: Campanha de Incentivo - GRUPO DE ATITUDE SOCIAL - Moradores de Rua>, <Project: APAE pede Socorro>, <Project: Campanha de Incentivo - Anjos da Madrugada>, <Project: Pintura de Casas Emergenciais com o TETO - São Paulo>, <Project: Campanha de Incentivo - Aos Olhos do Pai>, <Project: Legião da Boa Vontade>, <Project: Campanha de Incentivo - Você é a gota que faltava, Doe Sangue!>, <Project: Campanha de Incentivo - Sonhar com Esperança>, '...(remaining elements truncated)...']>
}}}


The 'closed' field here is a Boolean. Everything seems to be correct except for this:

{{{
>>> p[0]                                                   
<Project: Campanha de Incentivo - Anjos da Madrugada>
>>> p[1]
<Project: Bola na Rede>
}}}


When I get items from the queryset, they don't match the queryset __repr__ order. What is even weirder is that neither the __repr__ order nor the __getitem__ order matches the PostgreSQL query.


{{{
>>> print(p.query)
SELECT ""ovp_projects_project"".""id"", ""ovp_projects_project"".""image_id"", ""ovp_projects_project"".""address_id"", ""ovp_projects_project"".""owner_id"", ""ovp_projects_project"".""organization_id"", ""ovp_projects_project"".""name"", ""ovp_projects_project"".""slug"", ""ovp_projects_project"".""published"", ""ovp_projects_project"".""highlighted"", ""ovp_projects_project"".""applied_count"", ""ovp_projects_project"".""max_applies"", ""ovp_projects_project"".""max_applies_from_roles"", ""ovp_projects_project"".""public_project"", ""ovp_projects_project"".""minimum_age"", ""ovp_projects_project"".""hidden_address"", ""ovp_projects_project"".""crowdfunding"", ""ovp_projects_project"".""published_date"", ""ovp_projects_project"".""closed"", ""ovp_projects_project"".""closed_date"", ""ovp_projects_project"".""deleted"", ""ovp_projects_project"".""deleted_date"", ""ovp_projects_project"".""created_date"", ""ovp_projects_project"".""modified_date"", ""ovp_projects_project"".""details"", ""ovp_projects_project"".""description"" FROM ""ovp_projects_project"" ORDER BY ""ovp_projects_project"".""closed"" ASC
}}}


When hitting the database with such query, only removing a couple of fields to make it easier to read, this is what I get:
[[Image(https://code.djangoproject.com/attachment/ticket/28657/django-boolean-bug.png)]]

These are 3 different orders. Now, there's one little thing I can do to fix the QuerySet, which is iterating over it.

{{{
>>> for x in p:
...   print(x.pk)
... 
81
74
75
91
83
61
(...)
}}}


Suddenly the queryset now matches the result from my PostgreSQL query and everything is now correct.

{{{
>>> p
<QuerySet [<Project: Pintura de Casas Emergenciais com o TETO - São Paulo>, <Project: Campanha de Incentivo - Anjos da Madrugada>, <Project: Ong ong>, <Project: projeto luciele>, <Project: Campanha de Incentivo - Projeto Alimentando Vidas>, <Project: Campanha de Incentivo - Menos é Mais>, <Project: Campanha de Incentivo - Alimentando a Solidariedade (Outubro)>, <Project: Campanha de Incentivo - Aula de Música>, <Project: Campanha de Incentivo - Projeto Fora das 4 Paredes>, <Project: Campanha
de Incentivo - Padoca Artesanal>, <Project: Campanha de Incentivo - EmpoderA>, <Project: Campanha de Incentivo - Moto Sopa>, <Project: Campanha Incentivo - Projeto Vale Jequitinhonha>, <Project: Campanha de Incentivo - Eternas Crianças>, <Project: Campanha de Incentivo - Festa de Natal>, <Project: Treinador voluntário de futebol - Águias Livres>, <Project: Fundação Gol de Letra - Faça parte deste time!>, <Project: Campanha de Incentivo - Ganhando Almas>, <Project: Campanha de
Incentivo - Acolchoados de Ponto Cruz e Patchwork>, <Project: Campanha de Incentivo - Show de Encantamento Solidário>, '...(remaining elements truncated)...']>
>>> p[0]
<Project: Pintura de Casas Emergenciais com o TETO - São Paulo>
>>> p[1]
<Project: Campanha de Incentivo - Anjos da Madrugada>
}}}


I'm trying to find out where the problem is really happening but I have limited knowledge about django ORM internals, so I haven't gotten that far yet. Currently I'm hacking around it by iterating over the queryset before paginating it and passing it to my view.

Things get even weirder if I try to order by 2 boolean fields, with issues such as:

{{{
>>> p = Project.objects.all().order_by(""closed"", ""-highlighted"")                                                       
>>> p                                                      
<QuerySet [<Project: Campanha Incentivo - Projeto Vale Jequitinhonha>, <Project: Campanha de Incentivo - Alimentando a Solidariedade (Outubro)>, <Project: Campanha de Incentivo - Festa do Dia Das Crianças>, <Project: Campanha de Incentivo - Cartas para o ""Papai Noel"">, <Project: Pintura de Casas Emergenciais com o TETO - São Paulo>, <Project: Campanha de Incentivo - Padoca Artesanal>, <Project: Campanha de Incentivo - EmpoderA>, <Project: Construção de Casas Emergenciais com o TETO - São Paulo - Estrutura e entrega  da casa>, <Project: Campanha de Incentivo - Doação de Brinquedos>, <Project: Campanha de Incentivo - Pequena ajuda, grande transformação>, <Project: Campanha de Incentivo - Aula de Música>, <Project: Campanha de Incentivo - Aos Olhos do Pai>, <Project: APAE pede Socorro>, <Project: Campanha de Incentivo - GRUPO DE ATITUDE SOCIAL - Moradores de Rua>, <Project: Mãos Solidárias>, <Project: Campanha de Incentivo - Projeto Bolas de Pelos>, <Project: Campanha de Incentivo - Projeto Conviver>, <Project: Bola na Rede>, <Project: Campanha de Incentivo - Você é a gota que faltava, Doe Sangue!>, <Project: projeto luciele>, '...(remaining elements truncated)...']>
>>> p[0], p[0].pk
(<Project: Pintura de Casas Emergenciais com o TETO - São Paulo>, 81)
>>> p[1], p[1].pk
(<Project: Pintura de Casas Emergenciais com o TETO - São Paulo>, 81)
}}}
"	Bug	closed	Database layer (models, ORM)	1.11	Normal	invalid	queryset, boolean, order, ordering		Unreviewed	0	0	0	0	0	0
