Django order_by() в Python — метод сортировки
Django order_by используется в Python для сортировки строк по одному или нескольким столбцам в порядке возрастания или убывания.
Введение в метод order_by() в Django
При определении модели можно указать порядок результатов по умолчанию, возвращаемых QuerySet, используя параметр упорядочивания в классе Meta модели.
Для демонстрации мы будем использовать модель Employee. Модель Employee сопоставляется с таблицей hr_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:
В следующем примере функция 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).