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
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.
For py<2.6,
queryset.iterator().next()
For >= 2.6
next(queryset.iterator())
should do the trick
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With