updating a queryset throws an error upon iteration in python/django

Viewed 47

I have an ordered query that I want to append to a list and then split into sublists based on the price. My code is as follows:

def home(books):

grouped_books = []

for i in range(len(books) - 1):
    this_book = books[i].price
    next_book = books[i+1].price

    if this_book != next_book and price >= 100:
        r = books[:i+1]
        grouped_books.append(r)
        for ob in grouped_books:
           books = books.exclude(id__in=[o.id for o in ob])

Upon iterating after the query is updated, this code throws an error that list index is out of range

Am I doing something wrong here? I'd appreciate your help. Thanks!

1 Answers

A QuerySet is not a list. So using books[:i+1] makes not much sense. Furthermore you alter books. Indeed, you write books = books.exclude(…). This thus means that if you reduce the number of elements in the books queryset, the index will eventually go out of range. Note that the range(len(books) - 1) part is only evaluated at the beginning of the for loop. It is thus not updated.

I think however you make things too complicated. You can make a query where you order the books by price, and then use groupby(…) [Python-doc]:

from itertools import groupby
from operator import attrgetter

def home(books):
    return [
        list(vs)
        for __, vs in groupby(books.order_by('price'), attrgetter('price'))
    ]

or if you want to group per price range of 100:

from itertools import groupby

def home(books):
    return [
        list(vs)
        for __, vs in groupby(books.order_by('price'), lambda b: b.price // 100)
    ]
Related