#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.