Resumo : neste tutorial, você aprenderá como usar o Django order_by
para 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 QuerySet
usando a ordering
opção na Meta
classe 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_name
e na classe da seguinte maneira:last_name
ordering
Meta
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 ordering
opçã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 ordering
opçã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
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:order_by()
>>> 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_employee
e :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.