Django: avoid “useless use of .all()”

An animal with tusks. I am not sure what. I guess an extinct mammal. I just thought it was a cool picture and would help you remember this post.

Here’s a little ORM pet peeve of mine that may deepen your understanding of how QuerySets work.

Take this code:

Digger.objects.all().filter(height_cm__gt=200)

The .all() is unnecessary.

It’s equivalent to write:

Digger.objects.filter(height_cm__gt=200)

Why?

The manager, Digger.objects, already refers to all Digger objects. Calling .filter() creates a queryset from that manager, with some filtering. Add .all() only adds a useless copy of the queryset between these steps.

You only need .all() in a few cases:

  1. To create a queryset that intentionally refers to all objects, perhaps for later filtering or slicing:

    diggers = Digger.objects.all()
    paginator = Paginator(diggers, 50)
    ...
    
  2. To delete all objects:

    Digger.objects.all().delete()
    

    Django requires the .all() as confirmation to prevent accidental deletion of a whole table.

Useless calls to .all() aren’t a large problem, but they do mean more code to read and a slight performance cost for the extra queryset copies. I think that avoiding them also shows you understand ORM methods a little bit better.

Fin

May your querysets be lean and legible,

—Adam


Learn how to make your tests run quickly in my book Speed Up Your Django Tests.


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: