Skip to content

values/values_list usage

When dj-tracker detects that no model attributes/methods, except the ones needed to build model instances, are used for all instances of a queryset; it'll hint at using the .values or .values_list methods.

In our example, we're only using raw model fields, namely title, category.name, author.first_name and author.last_name; we aren't using any method or such. Therefore it's a candidate for the Use values/values_list hint:

dj-tracker Use values/values_list

View - Template

Let's update our view to use .values:

def books_list(request):
    books = Book.objects.values(
        "title",
        "category__name",
        "author__first_name",
        "author__last_name",
    )
    return render(request, "books.html", {"books": books})

Django will only fetch the fields we passed in to the .values method, so we can remove the .only call as it's redundant. See docs on the .values method.


Our query will now return dictionary objects instead of model instances. An instance will have the following structure:

{
    "title": "Harry Potter",
    "category__name": "Science Fiction",
    "author__first_name": "Joanne",
    "author__last_name": "Rowling"
}

Let's update our template to match this new structure:

{% for book in books %}
<h4>{{ book.title }}</h4>
<dl>
  <dt>Author</dt>
  <dd>{{ book.author__first_name }} {{ book.author__last_name }}</dd>

  <dt>Category</dt>
  <dd>{{ book.category__name }}</dd>
</dl>
{% endfor %}

Profile

Let's now run our profilers to see how our view performs:

Time in ms (10 calls) - Min: 86.58, Max: 115.77, Avg: 96.92

Memory - size in KiB (10 calls) - Min: 2303.49, Max: 2580.66, Avg: 2431.73
Memory - peak in KiB (10 calls) - Min: 5262.68, Max: 5544.66, Avg: 5392.42

Our new version is in average 2x faster (previous average was 219ms) and uses 2.5x less memory as well.

This can be explained by the fact that creating and manipulating dictionaries is cheaper than doing the same with model instances - both in speed and in memory terms.

This is now what the field stats for our query look like:

dj-tracker - Field stats

Summary

dj-tracker keeps track of every model atribute/method access to provide hints on when to use the .values or .values_list optimisations.

Another valuable optimisation method that dj-tracker can give hints about is the .iterator method. Check out the next steps for more on this.