On Oct 19, 3:45 pm, Ed <edmund.rog...@gmail.com> wrote:
> I have a table for Actor that I query and populate the result in
> actor_list to pass to the template. I installed the Django Debug
> Toolbar to check the queries hitting the database and found some
> strange behavior. If I iterate through the actor_list, only one SQL
> query is created, as expected:
>
> {% for actor in actor_list %}
>    {{ actor.id }}
> {% endfor %}
>
> But if I call a particular item in the list before the loop, that
> additional call generates its own query, meaning the database is hit
> twice.
>
> {{ actor_list.0.id }}
>
> {% for actor in actor_list %}
>    {{ actor.id }}
> {% endfor %}
>
> Why is that?  Is there a way to do this that doesn't result in two
> queries?

What's happening here is that calling {{ actor_list.0 }} slices the
queryset - it's the same as doing actor_list[0] in Python code. When
you slice a queryset, Django always evaluates it, if it hasn't done so
already. So in this case Django sends an SQL query with `LIMIT 1` on
the end, and returns just that element, from which you then take the
id value and throw it away. Then, Django encounters your loop. Now it
needs the whole queryset - so it needs to get *that* from the
database. Hence your extra query.

The solution here is to evaluate the queryset in your view first,
before passing it to the template. You can do this by simply calling
list() on it - eg instead of defining your context as {'actor_list':
actor_list}, do {'actor_list': list(actor_list)}. Bear in mind though,
if you're doing things like pagination, this will end up being less
efficient, as it will evaluate the *whole* queryset rather than just
the elements you need for the page you're on.
--
DR.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to