Sort a Django QuerySet with .order_by(): 'field' for ascending, '-field' for descending.
Example:
# Once upon a time, we ordered in ascending roadascending_qs = MyModel.objects.order_by('field')
# Then decided to walk down the descending Roaddescending_qs = MyModel.objects.order_by('-field')
Logical primer to ordering
Understanding the guts of Django order_by makes using it a breeze.
Ordering by related fields
Looking to order by a related model field? Here's how:
# Sorting party by related friends' agequeryset = MyModel.objects.order_by('relatedmodel__field')
Smushing multiple fields in order_by
Want to sort on several things? Chain them:
# Sorting concert by date (rock before pop), then by band name. Party on!queryset = MyModel.objects.order_by('-date', 'name')
Setting a default ordering
Picky about your default list order? Set it up in the Meta class:
classMyModel(models.Model):# ... fields here ...classMeta:# It's like mama always said, 'Name first, age second.' ordering = ('name', '-age')
Dynamic ordering
Life changes and so can your order_by:
# Life's pretty vanilla...order_field = 'field'# or '-field' for descending# ...until it's notqueryset = MyModel.objects.order_by(order_field)
Digging deeper into order_by
Play with order_by. Understand it, bend it to your will. Here's how:
How ordering treats null values
Deal with those pesky null pointers:
# When life gives you nulls, sort them to the lastqueryset = MyModel.objects.order_by('field', 'other_field')
# Unless you want 'em first. We don't judge.queryset = MyModel.objects.order_by(F('field').asc(nulls_first=True))
Mind your performance
Remember, order_by can also mean wait_for_it on large datasets:
# Ordering for ants? Fast.# Ordering for elephants? Umm...large_query_set = LargeModel.objects.order_by('-date', 'category', 'name')
It's your order, flip it!
Don't let order_by control you. Exercise your right to reverse:
# Ordered pizza but felt like sushi? Just reverse!queryset = MyModel.objects.order_by('field').reverse()
Advanced ordering methods
Master order_by, use it like you invented it. Here are cool tricks:
Null-safe fields with SQL expressions
Turn null feel-sorry-for-me into null look-at-me-nailing-it:
# When life gives you nulls, make zero lemonades!queryset = MyModel.objects.annotate(null_safe_field=Coalesce('field_with_nulls', 0)).order_by('null_safe_field')
Optimising JOINs in ordering
Too many JOIN operations? Don't get stuck, get optimizing:
# Optimise queryset ordering with foreign key fields.MyModel.objects.select_related('foreign_key_field').order_by('foreign_key_field__related_field')
Custom ordering functions
Conquer world, or just simply custom sort it:
# Be that nerdy party-goer who orders people by name length.from django.db.models import Func
classLength(Func): function = 'LENGTH'queryset = MyModel.objects.annotate(field_length=Length('name')).order_by('field_length')
Error-proofing
Remember, the only certainties in life are death and AttributeError:
# Well, we tried, and we caught. Life moves on.try:
queryset = MyModel.objects.order_by('nonexistent_field')
except FieldError:
queryset = MyModel.objects.order_by('default_field')