Django queryset filter by list - получение элементов списка, которые не найдены

Допустим, есть модель django Data с полем символов hash и списком хэшей all_hashes. Теперь понятно, что можно использовать выражение фильтрации для получения всех объектов в Data, которые находятся внутри списка хэшей, используя синтаксис __in, например:

all_hashes = ['45df...','ab23...', ... ]
filtered_data = Data.objects.filter(hash__in=all_hashes)

Таким образом, если кто-то хочет узнать, какие хэши были найдены, можно просто сделать

filtered_hashes = [obj.hash for obj in filtered_data]

И вы можете получить хэши, которые не были найдены, как

new_hashes = set(all_hashes) - set(filtered_hashes)

Конечно, вы также можете напрямую получить new_hashes, проходя один за другим по списку all_hashes и по отдельности пытаясь получить соответствующий объект из базы данных, однако это похоже на то, что это вызовет много запросов и этого следует избегать.

Вопрос в том, есть ли более прямой способ определить, для каких элементов списка не удалось найти подходящий объект - возможно, что-то вроде:

objects_existing = Data.objects.exist(hash__in=all_hashes) => [true, false, ...]

В качестве возможного решения, попробуйте:

objects_existing = Data.objects.annotate(hash_in_all_hashes=Exists(Data.objects.filter(id=OuterRef('id'), hash__in=all_hashes)))

Теперь вы можете выполнять итерации над objects_existing, например:

hash_in_all_hashes = [obj.hash_in_all_hashes for obj in objects_existing] => [True, False, ...]

Ор:

hash_in_all_hashes_list = list(objects_existing.values_list('hash_in_all_hashes', flat=True)) => [True, False, ...]
Вернуться на верх