BETWEEN
次のコードは、Django QuerySetに対して上記のErwinの回答を(を使用して)実装します。
任意のDjangoQuerySetに対してこれを行うユーティリティ関数は次のとおりです。between
デフォルトでは、「id」が句に使用するのに適したフィールドであると想定しています。
def chunked_queryset(qs, batch_size, index='id'):
"""
Yields a queryset split into batches of maximum size 'batch_size'.
Any ordering on the queryset is discarded.
"""
qs = qs.order_by() # clear ordering
min_max = qs.aggregate(min=models.Min(index), max=models.Max(index))
min_id, max_id = min_max['min'], min_max['max']
for i in range(min_id, max_id + 1, batch_size):
filter_args = {'{0}__range'.format(index): (i, i + batch_size - 1)}
yield qs.filter(**filter_args)
これは次のように使用されます。
for chunk in chunked_queryset(SomeModel.objects.all(), 20):
# `chunk` is a queryset
for item in chunk:
# `item` is a SomeModel instance
pass
余分なネストされたループを必要としないようにインターフェースを変更することもできますが、次のことができますfor item in chunked_queryset(qs)
。
def chunked_queryset(qs, batch_size, index='id'):
"""
Yields a queryset that will be evaluated in batches
"""
qs = qs.order_by() # clear ordering
min_max = qs.aggregate(min=models.Min(index), max=models.Max(index))
min_id, max_id = min_max['min'], min_max['max']
for i in range(min_id, max_id + 1, batch_size):
filter_args = {'{0}__range'.format(index): (i, i + batch_size - 1)}
for item in qs.filter(**filter_args):
yield item