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