Kevin Wang
Kevin Wang

Reputation: 3330

Django - When is a query made?

I want to minimize the number of database queries my application makes, and I am familiarizing myself more with Django's ORM. I am wondering, what are the cases where a query is executed.

For instance, this format is along the lines of the answer I'm looking for (for example purposes, not accurate to my knowledge):

I am assuming curried filter operations never make additional requests, but from the docs it looks like filter() does indeed make database requests if it's the first thing called.

Upvotes: 1

Views: 230

Answers (2)

Adrián
Adrián

Reputation: 6255

If you're using test cases, you can use this custom assertion included in django's TestCase: assertNumQueries().

Example:

with self.assertNumQueries(2):
    x = SomeModel.objects.get(pk=1)
    y = x.some_foreign_key_in_object

If the expected number of queries was wrong, you'd see an assertion failed message of the form:

Num queries (expected - actual):
    2 : 5

In this example, the foreign key would cause an additional query even though there's no explicit query (get, filter, exclude, etc.).

For this reason, I would use a practical approach: Test or logging, instead of trying to learn each of the cases in which django is supposed to query.


If you don't use unit tests, you may use this other method which prints the actual SQL statements sent by django, so you can have an idea of the complexity of the query, and not just the number of queries:

(DEBUG setting must be set to True)

from django.db import connection

x = SomeModel.objects.get(pk=1)
y = x.some_foreign_key_in_object

print connection.queries

The print would show a dictionary of queries:

[
 {'sql': 'SELECT a, b, c, d ... FROM app_some_model', 'time': '0.002'},
 {'sql': 'SELECT j, k, ... FROM app_referenced_model JOIN ... blabla ', 
      'time': '0.004'}
]

Docs on connection.queries.

Of course, you can also combine both methods and use the print connection.queries in your test cases.

Upvotes: 2

Bernhard Vallant
Bernhard Vallant

Reputation: 50786

See Django's documentation on when querysets are evaluated: https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated

Evaluation in this case means that the query is executed. This mostly happens when you are trying to access the results, eg. when calling list() or len() on it or iterating over the results.

get()in your example doesn't return a queryset but a model objects, therefore it is evaluated immediately.

Upvotes: 2

Related Questions