#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
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