• In general, the results of a QuerySet aren’t fetched from the database until you “ask” for them. When you do, the QuerySet is evaluated by accessing the database. –lazy qeury
  • Caching and QuerySets
    1. In general, attributes that are not callable will be cached.
    2. In general, callable attributes cause DB lookups every time

To make use of the caching behavior of QuerySet, you may need to use the with template tag.

If you only need a foreign key value, use the foreign key value that is already on the object you’ve got, rather than getting the whole related object and taking its primary key. i.e. do: entry.blog_id instead of entry.blog.id

@cached_property

It is up to you to implement caching when required. Say in your model and there’s an expensive computation method in this model, you can cache this method so that if it’s used once, it won’t be loaded twice for it to use again.

Database Execution

When a query will be executed:

  • iteration: for i in Blog.objects.all(): ...
  • get:
    • get an object with a unique field: e = Entry.objects.get(pk=5) and then another separate query if below:
    • get a related object: b = e.blog
    • to avoid: e = Entry.objects.select_related('blog').get(pk=5) only hit database once if more queries on Blog model/table

diff between if query and if query.exist()

Does the same thing but the mechanisms are different, hence, the efficiency.

  • When to use:
    • Just want to check whether the queryset is/isn’t empty - has at least 1 result
    • Just want to check whether a in b? - more efficient: b.filter(id=a.id).exist()
    • Additional to the above, in a large queryset
  • when to not use
    • NOT when you know you will run this query anyway later
  • Refs:

Overall ref django official doc: