Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to slice a Django queryset without hitting the database more than once

Tags:

django

I'm running a query to get the 5 latest News items. In my template, I want to display the first item in one location, then the remaining 4 further down the page.

In my template, I do something like this:

{% for n in news|slice:":1" %}
    {{ n.headline }}
{% endfor %}

... more HTML ...

{% for n in news|slice:"1:" %}
    {{ n.headline }}
{% endfor %}

When I look in the Debug Toolbar, this results in two queries to the database: one with LIMIT 1 and another with LIMIT 4 OFFSET 1, but otherwise the same. I appreciate this is Django's way of intelligently only requesting the stuff you actually use, but in this case it seems a little excessive. What's the best way to do this kind of thing?

like image 229
Matt Andrews Avatar asked Feb 25 '12 18:02

Matt Andrews


2 Answers

Convert to a sequence in the view, then slice the sequence.

var = list(somequery[:5])
like image 60
Ignacio Vazquez-Abrams Avatar answered Sep 20 '22 21:09

Ignacio Vazquez-Abrams


You just need to force the queryset to evaluate itself before the slice. This could be done as simply as calling len() on it in your view before passing it off to the context.

The Django docs have a complete list of everything that causes a queryset to evaluate. Just do something from that list and you're good.

like image 32
Chris Pratt Avatar answered Sep 23 '22 21:09

Chris Pratt