Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get next row on a django queryset?

Tags:

django

I have a queryset with that will return several rows in it. One of the row has a slug "slug-456", how do I get to the next row after that row having the slug "slug-456" with respect to the current ordering the queryset have?

I can loop through the queryset and check if the current row has the slug "slug-456" and if it has take note that the next row is what I'm after, but Is there a more efficient way?

UPDATE: I did it this way:

id_list = list(qs.values_list('id', flat=True))
try:
    next_id = id_list[id_list.index(obj.id) + 1]
    obj = Object.objects.get(id=next_id)
except IndexError:
    pass
like image 753
Marconi Avatar asked Feb 13 '11 14:02

Marconi


2 Answers

Querysets are generators so there isn't really a shortcut along the lines of qs[qs.indexof(slug="..")+1]. Any solution you come up with still require iterating through the queryset (at least till the target object).

As you mention, a possible way to do it would be to loop through the queryset and return the one right after the one with slug="slug-456".

You could of course take a more convoluted route and do something along the lines of:

# get slugs in order
sio = list(qs.objects.values_list('slug', flat=True))
target_slug = sio[sio.index(sio) + 1] # watch for KeyError
your_object = qs.objects.get(slug__exact=target_slug)

while amusing to write, this is unlikely to give any performance benefits (unless your model has many fields in which case iterating through the output of values_list() first might be beneficial).

Related answer: Get the index of an element in a queryset.

like image 27
Shawn Chin Avatar answered Sep 24 '22 02:09

Shawn Chin


For py<2.6,

queryset.iterator().next()

For >= 2.6

next(queryset.iterator())

should do the trick

like image 103
Almad Avatar answered Sep 23 '22 02:09

Almad