views:

37

answers:

2

I have two tables: Actor and Images. The Images table is linked to the Actor table through a Foreign Key. I might make a query on Actor that pulls a list of all the actors with first name beginning with the letter A. Let's say I store this query result in actor_list and pass it to the template. I can get a list of all the Images through the template by iterating. Something like:

{% for actor in actor_list %}
    {% for image in actor.img_set %}
       {{ image }}
    {% endfor %}
{% endfor %}

Is this costly to the database? Does the associated img_set come through with the initial actor object list, or does a new query hit the database every time I call for the actor.img_set?

A: 

You should install the Django debug toolbar and see what SQL queries are happening under the covers.

If you are getting too many queries, you can try using select_related() to pull in the related data in the initial query.

Ned Batchelder
Agree with the debug-toolbar recommendation, but `select_related()` won't help in the case of a reverse relation, which this appears to be.
Daniel Roseman
@ed: In addition to Daniel's comment and your last question: If it's a reverse relation the database will be hit for every actor to get his image set...
lazerscience
Thanks for input. Follow-up question. After checking the SQL from the Django Debug Toolbar, I see that the database is getting hit for even this: {{ actor_list.0.id }}. Why does a SQL query go out when actor_list has already been created? But no additional query is created if I iterate through the actor_list and pull the id that way
Ed
A: 

Better than using the django toolbar is using the connections library. With Debug set to True:

>>> from django.db import connection
>>> for actor in actor_list:
>>>  for image in actor.img_set:
>>>   image
>>> connection.queries()

This will show all the queries that were executed and the amount of time that each took.

The debug toolbar is cool, though, for many uses. :-)

Justin Myles Holmes