Django order_by() в Python — метод сортировки

Django order_by используется в Python для сортировки строк по одному или нескольким столбцам в порядке возрастания или убывания.

Введение в метод order_by() в Django

При определении модели можно указать порядок результатов по умолчанию, возвращаемых QuerySet, используя параметр упорядочивания в классе Meta модели.

Для демонстрации мы будем использовать модель Employee. Модель Employee сопоставляется с таблицей hr_employee в базе данных:

Пример модели Employee

Например, чтобы отсортировать сотрудников по имени и фамилии в алфавитном порядке, можно указать поля first_name и last_name в качестве параметра упорядочивания в классе Meta следующим образом:

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

    class Meta:
        ordering = ['first_name', 'last_name']

Чтобы отсортировать значения в порядке убывания, добавьте символ — перед именем поля. Например, ниже используется опция упорядочивания для сортировки сотрудников по имени в порядке убывания и по фамилии в порядке возрастания:

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

    class Meta:
        ordering = ['-first_name', 'last_name']

Кроме того, вы можете использовать выражение запроса, чтобы значения NULL отображались первыми или последними в отсортированном результате:

from django.db.models import F

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

    class Meta:
        ordering = [F('first_name').asc(nulls_last=True)]

Чтобы переопределить порядок сортировки по умолчанию, используйте метод order_by() объекта QuerySet:

order_by(*fields)

В следующем примере функция order_by() используется для сортировки сотрудников по имени в порядке возрастания:

>>> 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)...']>

Как и в случае с опцией упорядочивания, вы можете использовать метод order_by() для сортировки сотрудников по имени в порядке убывания:

>>> 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)...']>

Order_by() также позволяет сортировать результаты по нескольким полям. Например, следующий пример использует 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)...']>

Чтобы сделать заказ случайным образом, вы можете использовать вопросительный знак ?, например:

>>> 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)...']>

Order_by(‘?’) может быть медленным и дорогим, в зависимости от используемой вами базы данных. Сгенерированный выше SQL взят из PostgreSQL. Другие базы данных могут иметь другие реализации.

Сортировка по связанным моделям

Order_by() позволяет вам упорядочить по полю в связанной модели. Синтаксис поля — связанная модель, за которой следуют двойные подчеркивания и имя поля:

Entity.objects.order_by(related_model__field_name)

Для демонстрации мы будем использовать модели Employee и Department. Модели Employee и Department сопоставляются с таблицами hr_employee и hr_department:

Пример моделей Employee и Department

В следующем примере функция order_by() используется для сортировки сотрудников по названиям их отделов:

>>> 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)...']>

Сгенерированный SQL-код показывает, что при упорядочивании по полю в связанной модели Django использует соединение, которое объединяет таблицу текущей модели(Employee) с таблицей связанной модели(Department).

Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *