'Yield a queryset in chunks of at most ``chunk_size``. The chunk yielded
will be a list, not a queryset. Iterating over the chunks is done in a
transaction so that the order and count of items in the queryset
remains stable.'

@transaction.atomic
def queryset_chunks(self, qs, chunk_size=1000):

    i = 0
    while True:
        items = list(qs[(i * chunk_size):][:chunk_size])
        if (not items):
            break
        (yield items)
        i += 1
