Django order_by

Resumo : neste tutorial, você aprenderá como usar o Django order_bypara classificar linhas por uma ou mais colunas em ordem crescente ou decrescente.

Introdução ao método order_by() do Django

Ao definir um modelo , você pode especificar a ordem padrão dos resultados retornados por a QuerySetusando a orderingopção na Metaclasse do modelo.

Usaremos o modelo Employee para a demonstração. O modelo Employee é mapeado para a tabela hr_employee no banco de dados:

Por exemplo, para classificar o funcionário por nome e sobrenome em ordem alfabética, você pode especificar a opção nos campos first_namee na classe da seguinte maneira:last_nameorderingMeta

class Employee(models.Model):
    # ...

    class Meta:
        ordering = ['first_name', 'last_name']
Linguagem de código:  Python  ( python )

Para classificar os valores em ordem decrescente, adicione o -caractere na frente do nome do campo. Por exemplo, o seguinte usa a orderingopção de classificar os funcionários por nome em ordem decrescente e sobrenome em ordem crescente:

class Employee(models.Model):
    # ...

    class Meta:
        ordering = ['-first_name', 'last_name']
Linguagem de código:  Python  ( python )

Além disso, você pode usar uma expressão de consulta para fazer com que os valores nulos apareçam primeiro ou por último no resultado classificado:

from django.db.models import F

class Employee(models.Model):
    # ...

    class Meta:
        ordering = [F('first_name').asc(nulls_last=True)]
Linguagem de código:  Python  ( python )

Para substituir a ordem de classificação padrão, você usa o order_by()método de a QuerySet:

order_by(*fields)Linguagem de código:  Python  ( python )

O exemplo a seguir usa order_by()para classificar os funcionários pelo nome em ordem crescente:

>>> Employee.objects.all().order_by('first_name')             
SELECT "hr_employee"."id",
       "hr_employee"."first_name",
       "hr_employee"."last_name",
       "hr_employee"."contact_id",
       "hr_employee"."department_id"
  FROM "hr_employee"
 ORDER BY "hr_employee"."first_name" ASC
 LIMIT 21
Execution time: 0.001034s [Database: default]
<QuerySet [<Employee: Aaron Pearson>, <Employee: Adam Crane>, <Employee: Adam Stewart>, <Employee: Adrienne Green>, <Employee: Alan Johnson>, <Employee: Alexa West>, <Employee: Alicia Wyatt>, <Employee: Amanda Benson>, <Employee: Amber Brown>, <Employee: Amy Lopez>, <Employee: Amy Lee>, <Employee: Andre Perez>, <Employee: 
Andrea Mcintosh>, <Employee: Andrew Guerra>, <Employee: Andrew Dixon>, <Employee: Ann Chang>, <Employee: Anne Odom>, <Employee: Anthony Welch>, <Employee: Anthony Fuentes>, <Employee: Ashley Brown>, '...(remaining elements truncated)...']>
Linguagem de código:  Python  ( python )

Assim como a orderingopção, você pode usar o order_by()método para classificar o funcionário pelo primeiro nome em ordem decrescente:

>>> Employee.objects.all().order_by('-first_name') 
SELECT "hr_employee"."id",
       "hr_employee"."first_name",
       "hr_employee"."last_name",
       "hr_employee"."contact_id",
       "hr_employee"."department_id"
  FROM "hr_employee"
 ORDER BY "hr_employee"."first_name" DESC
 LIMIT 21
Execution time: 0.000998s [Database: default]
<QuerySet [<Employee: William Wise>, <Employee: Wendy Reilly>, <Employee: Victoria Forbes>, <Employee: Victoria Schneider>, <Employee: Vicki Baker>, <Employee: Veronica Blackburn>, <Employee: Vanessa Allen>, <Employee: Valerie Nguyen>, <Employee: Tyler Coleman>, <Employee: Tyler Briggs>, <Employee: Troy Ashley>, <Employee: Travis Goodwin>, <Employee: Tony Jordan>, <Employee: Todd Evans>, <Employee: Timothy Dillon>, <Employee: Timothy Mckay>, <Employee: Timothy Williams>, <Employee: Timothy Lewis>, <Employee: Tiffany Holt>, <Employee: Tiffany Jackson>, '...(remaining elements truncated)...']>
Linguagem de código:  Python  ( python )

O order_by()também permite classificar os resultados por vários campos. Por exemplo, o seguinte usa para order_by()classificar funcionários por nome e sobrenome:

>>> Employee.objects.all().order_by('first_name','last_name')
SELECT "hr_employee"."id",
       "hr_employee"."first_name",
       "hr_employee"."last_name",
       "hr_employee"."contact_id",
       "hr_employee"."department_id"
  FROM "hr_employee"
 ORDER BY "hr_employee"."first_name" ASC,
          "hr_employee"."last_name" ASC
 LIMIT 21
Execution time: 0.000998s [Database: default]
<QuerySet [<Employee: Aaron Pearson>, <Employee: Adam Crane>, <Employee: Adam Stewart>, <Employee: Adrienne Green>, <Employee: Alan Johnson>, <Employee: Alexa West>, <Employee: Alicia Wyatt>, <Employee: Amanda Benson>, <Employee: Amber Brown>, <Employee: Amy Lee>, <Employee: Amy Lopez>, <Employee: Andre Perez>, <Employee: 
Andrea Mcintosh>, <Employee: Andrew Dixon>, <Employee: Andrew Guerra>, <Employee: Ann Chang>, <Employee: Anne Odom>, <Employee: Anthony Fuentes>, <Employee: Anthony Welch>, <Employee: Ashley Brown>, '...(remaining elements truncated)...']>
Linguagem de código:  Python  ( python )

Para ordenar aleatoriamente, você pode usar um ponto de interrogação ?como este:

>>> Employee.objects.all().order_by('?')                      
SELECT "hr_employee"."id",
       "hr_employee"."first_name",
       "hr_employee"."last_name",
       "hr_employee"."contact_id",
       "hr_employee"."department_id"
  FROM "hr_employee"
 ORDER BY RANDOM() ASC
 LIMIT 21
Execution time: 0.010370s [Database: default]
<QuerySet [<Employee: Daniel Meyer>, <Employee: Todd Evans>, <Employee: Roger Robinson>, <Employee: Dwayne Williams>, <Employee: Michael Murphy>, <Employee: Daniel Friedman>, <Employee: Claudia Aguilar>, <Employee: Craig Hunter>, <Employee: Amanda Benson>, <Employee: Renee Wright>, <Employee: Wendy Reilly>, <Employee: Jamie Jackson>, <Employee: Philip Jones>, <Employee: Kelly Stewart>, <Employee: Barbara Vincent>, <Employee: Drew Gonzalez>, <Employee: Derek Owens>, <Employee: Lauren Mcdonald>, <Employee: Perry Rodriguez>, <Employee: Matthew Hernandez>, '...(remaining elements truncated)...']>
Linguagem de código:  Python  ( python )

O order_by(‘?’) pode ser lento e caro, dependendo do banco de dados que você está usando. O gerado acima SQLé do PostgreSQL. Outros bancos de dados podem ter implementações diferentes.

Ordenação por modelos relacionados

O order_by()permite ordenar por um campo em um modelo relacionado. A sintaxe do campo é o modelo relacionado, seguido de sublinhados duplos e do nome do campo:

Entity.objects.order_by(related_model__field_name)Linguagem de código:  Python  ( python )

Usaremos os modelos Funcionário e Departamento para a demonstração. Os modelos Funcionário e Departamento são mapeados para as tabelas hr_employeee :hr_department

O exemplo a seguir usa order_by()para classificar os funcionários pelos nomes dos departamentos:

>>> Employee.objects.all().order_by('department__name')
SELECT "hr_employee"."id",
       "hr_employee"."first_name",
       "hr_employee"."last_name",
       "hr_employee"."contact_id",
       "hr_employee"."department_id"
  FROM "hr_employee"
 INNER JOIN "hr_department"
    ON ("hr_employee"."department_id" = "hr_department"."id")
 ORDER BY "hr_department"."name" ASC
 LIMIT 21
Execution time: 0.037173s [Database: default]
<QuerySet [<Employee: Brandy Morris>, <Employee: Jay Carlson>, <Employee: Jessica Lewis>, <Employee: Amanda Benson>, <Employee: Jacqueline Weaver>, <Employee: Patrick Griffith>, <Employee: Adam Stewart>, <Employee: Tiffany Holt>, <Employee: Amber Brown>, <Employee: Martin Raymond>, <Employee: Kyle Pratt>, <Employee: Cheryl Thomas>, <Employee: Linda Garcia>, <Employee: Jeanette Hendrix>, <Employee: Kimberly Gallagher>, <Employee: Kelly Stewart>, <Employee: Alan Johnson>, <Employee: 
William Wise>, <Employee: Debra Webb>, <Employee: Ryan Garcia>, '...(remaining elements truncated)...']>
Linguagem de código:  Python  ( python )

O SQL gerado mostra que ao ordenar por um campo em um modelo relacionado, o Django usa uma junção que une a tabela do modelo atual ( Employee) com a tabela do modelo relacionado ( Department).

Resumo

  • Use Django order_by()para classificar dados por um ou mais campos em ordem crescente ou decrescente.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *