Lesson 36 of 60 – Ordering Data in Django
60%

Ordering Data in Django

Ordering data means arranging database records in a particular sequence. Django ORM provides the order_by() method to sort QuerySet results based on one or more model fields.

Note: By default, order_by() sorts values in ascending order. Add a minus sign (-) before a field name to sort it in descending order.

1. What is Ordering?

Ordering means arranging records according to a specific field. For example, students can be ordered by name, age, admission date, or ID.

Student.objects.order_by("name")

This returns students ordered by their name.

2. The order_by() Method

The order_by() method is used to specify the ordering of a QuerySet.

students = Student.objects.order_by(
    "name"
)

The result is a QuerySet sorted by the specified field.

3. Ascending Order

When a field name is provided without a minus sign, Django orders the results in ascending order.

students = Student.objects.order_by(
    "name"
)

For names, this generally means A to Z. For numbers, it means smaller values to larger values.

4. Descending Order

To sort in descending order, place a minus sign before the field name.

students = Student.objects.order_by(
    "-name"
)

For names, this generally means Z to A. For numbers, larger values come before smaller values.

5. Ordering by Age

You can order student records by their age.

students = Student.objects.order_by(
    "age"
)

This sorts students from the lowest age to the highest age.

students = Student.objects.order_by(
    "-age"
)

This sorts students from the highest age to the lowest age.

6. Ordering by Name

Names can be ordered alphabetically.

students = Student.objects.order_by(
    "name"
)

This is useful for displaying student lists alphabetically.

7. Ordering by ID

You can order records using the primary key or ID.

students = Student.objects.order_by(
    "id"
)

This orders records by ID from smaller to larger.

students = Student.objects.order_by(
    "-id"
)

This places records with larger IDs first.

8. Ordering by Date

Date fields can also be used for ordering.

students = Student.objects.order_by(
    "admission_date"
)

This orders records from earlier dates to later dates.

students = Student.objects.order_by(
    "-admission_date"
)

This places the latest dates first.

9. Ordering by Multiple Fields

You can provide multiple fields to order_by().

students = Student.objects.order_by(
    "course",
    "name"
)

Django first orders by course. If multiple records have the same course, their names are then used for the next ordering level.

10. Multiple Fields with Descending Order

Each field can have its own ordering direction.

students = Student.objects.order_by(
    "course",
    "-age"
)

Records are ordered by course ascending and age descending within each course.

11. Ordering After filter()

You can filter records first and then order the resulting QuerySet.

students = Student.objects.filter(
    is_active=True
).order_by(
    "name"
)

This retrieves active students and sorts them by name.

12. Filtering and Descending Ordering

Filtering and descending ordering can also be combined.

students = Student.objects.filter(
    is_active=True
).order_by(
    "-age"
)

The oldest active students appear first.

13. Ordering with Search

A search QuerySet can also be ordered.

students = Student.objects.filter(
    name__icontains="rah"
).order_by(
    "name"
)

This searches for matching names and sorts the results alphabetically.

14. Ordering with first()

Ordering can be combined with first() to retrieve the first record according to a particular order.

student = Student.objects.order_by(
    "age"
).first()

This retrieves the student with the lowest age according to the QuerySet ordering.

15. Ordering with last()

The last() method can be used after ordering.

student = Student.objects.order_by(
    "age"
).last()

This retrieves the last object according to the specified ordering.

16. Ordering by Boolean Fields

Boolean fields can also be used for ordering.

students = Student.objects.order_by(
    "-is_active"
)

The exact ordering of boolean values can depend on the database backend. For predictable application behavior, consider the specific values and database being used.

17. Ordering with NULL Values

Some fields may contain NULL values. Django provides expressions for controlling whether NULL values appear first or last.

from django.db.models import F

students = Student.objects.order_by(
    F("phone").asc(nulls_last=True)
)

Here, records with NULL phone values are placed after non-NULL values.

18. Ascending and Descending with F()

The F() expression provides additional control over ordering.

from django.db.models import F

students = Student.objects.order_by(
    F("age").desc()
)

This orders the records by age in descending order.

19. Ordering Related Fields

You can order records using fields from related models with double-underscore notation.

students = Student.objects.order_by(
    "course__name"
)

If Student has a ForeignKey named course, this orders students using the related Course name.

20. Ordering with values()

You can order a QuerySet and then select specific fields using values().

students = Student.objects.order_by(
    "name"
).values(
    "name",
    "email"
)

The returned dictionaries contain the selected fields in the specified QuerySet order.

21. Removing Default Ordering

If a model defines default ordering in its Meta class, you can clear it for a particular QuerySet using order_by() with no arguments.

students = Student.objects.order_by()

This removes the model's default ordering for that QuerySet.

22. Default Ordering with Meta

A model can define a default ordering using the Meta class.

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    age = models.IntegerField()

    class Meta:
        ordering = ["name"]

Queries for this model will use the specified default ordering unless another ordering is applied.

23. Overriding Default Ordering

A QuerySet can override the model's default ordering.

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    class Meta:
        ordering = ["name"]

You can override it:

students = Student.objects.order_by(
    "-id"
)

The QuerySet is now ordered by ID descending.

24. Ordering in a View

Ordering is commonly used inside Django views before sending records to a template.

from django.shortcuts import render
from .models import Student

def student_list(request):

    students = Student.objects.order_by(
        "name"
    )

    return render(
        request,
        "students/list.html",
        {
            "students": students
        }
    )

25. Dynamic Ordering

An application can allow users to select a sorting field. User-provided values should be validated against an allowed list before being used in a query.

allowed_fields = [
    "name",
    "age",
    "id"
]

sort = request.GET.get(
    "sort",
    "name"
)

if sort not in allowed_fields:
    sort = "name"

students = Student.objects.order_by(
    sort
)

Using an allow-list prevents unexpected field names from being accepted.

26. Dynamic Ascending and Descending Order

You can allow a validated field to be sorted in either direction.

allowed_fields = [
    "name",
    "age",
    "id"
]

sort = request.GET.get(
    "sort",
    "name"
)

direction = request.GET.get(
    "direction",
    "asc"
)

if sort not in allowed_fields:
    sort = "name"

if direction == "desc":
    sort = "-" + sort

students = Student.objects.order_by(
    sort
)

Only validated field names should be used in dynamic ordering.

27. Pagination with Ordering

Ordering is especially important when displaying paginated data because a consistent ordering makes page results more predictable.

students = Student.objects.order_by(
    "id"
)

The ordered QuerySet can then be passed to Django's Paginator.

from django.core.paginator import (
    Paginator
)

paginator = Paginator(
    students,
    10
)

28. Complete Ordering Example

from django.shortcuts import render
from .models import Student

def student_list(request):

    students = Student.objects.filter(
        is_active=True
    ).order_by(
        "course",
        "name"
    )

    return render(
        request,
        "students/list.html",
        {
            "students": students
        }
    )

This example retrieves active students, orders them by course, and then orders students with the same course by name.

29. Common Ordering Mistakes

  • Forgetting to use order_by() when a specific order is required.
  • Forgetting the minus sign for descending order.
  • Using an incorrect model field name.
  • Using unvalidated user input for dynamic ordering.
  • Forgetting that multiple fields are applied in sequence.
  • Assuming database ordering without explicitly specifying it.
  • Ignoring NULL behavior when a field can contain NULL values.
  • Forgetting default ordering defined in the model's Meta class.
  • Not using a stable ordering when implementing pagination.

30. Summary of Ordering Data

Django's order_by() method provides a simple way to arrange QuerySet results.

  • order_by("name") sorts in ascending order.
  • order_by("-name") sorts in descending order.
  • Multiple fields can be supplied to order_by().
  • Filtering and ordering can be combined.
  • Date, numeric, text, and related fields can be used for ordering.
  • Meta.ordering can define default model ordering.
  • order_by() with no arguments clears default ordering.
  • F() expressions provide additional ordering control.
  • Dynamic ordering should use an allow-list of valid field names.
  • Consistent ordering is useful when implementing pagination.

📌 Key Points

  • order_by() is used to sort QuerySet results.
  • Ascending order uses the field name directly.
  • Descending order uses a minus sign before the field name.
  • Multiple fields can be used for multi-level ordering.
  • Ordering can be combined with filter() and other QuerySet methods.
  • Meta.ordering defines default ordering for a model.
  • F() expressions can provide additional ordering options.
  • Related fields can be ordered using double-underscore notation.
  • Dynamic ordering should validate user-selected fields.
  • Stable ordering is especially useful for paginated data.

🧠 Quick Quiz

Question: Which Django ORM method is used to sort QuerySet results?