Bin
2025-12-17 2b99d77d73ba568beff0a549534017caaad8a6de
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from core.feature_flags import flag_set
from django.conf import settings
 
 
def iterate_queryset(queryset, chunk_size=None):
    if chunk_size is None:
        chunk_size = settings.QS_ITERATOR_DEFAULT_CHUNK_SIZE
 
    if chunk_size <= 0:
        raise ValueError(f'chunk_size must be positive, got {chunk_size}')
 
    if not flag_set('fflag_fix_back_plt_863_remove_iterator_27082025_short', user='auto'):
        for obj in queryset.iterator(chunk_size=chunk_size):
            yield obj
        return
 
    model = queryset.model
    pk_field = model._meta.pk.name
 
    all_ids = list(queryset.values_list(pk_field, flat=True))
 
    if not all_ids:
        return
 
    for i in range(0, len(all_ids), chunk_size):
        chunk_ids = all_ids[i : i + chunk_size]
 
        # Create a new queryset based on the original, preserving all optimizations:
        # annotations, select_related, prefetch_related, only/defer
        chunk_qs = queryset.filter(**{f'{pk_field}__in': chunk_ids})
 
        for obj in chunk_qs:
            yield obj