#28657: Strangely odd behaviour when ordering QuerySet by BooleanField.
-------------------------------------+-------------------------------------
               Reporter:  Leonardo   |          Owner:  nobody
  Arroyo                             |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  1.11
  layer (models, ORM)                |       Keywords:  queryset, boolean,
               Severity:  Normal     |  order, ordering
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 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(blob:https://imgur.com/c888a1a0-cf27-44f4-b3d5-3a91174eb9ab)]]

 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)
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/28657>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/057.9ebe6e5ff2e946d3129caaf2964f3594%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to