Фильтрация Django по списку объектов модели

#python #django #django-queryset #intersection #django-filter

#python #django #django-набор запросов #пересечение #django-filter

Вопрос:

Я пытаюсь отфильтровать набор запросов, проверив, что объект находится в списке этих объектов.

 employee_list = [<Employee: A>, <Employee: B>, <Employee: C>]
qs = Employee.objects.filter(id__in=employee_list, [other_filters])
  

После выполнения выше qs представляет собой пустой список. Я думал, что мог бы создать новый список, такой как

 employee_ids = [emp.id for emp in employee_list]
qs = Employee.objects.filter(id__in=employee_ids, [other_filters])
  

Я не проводил сравнительный анализ этого метода, но я полагаю, что производительность, вероятно, пострадает. В качестве альтернативы я мог бы впоследствии пересекать списки следующим образом:

 qs = Employee.objects.filter([other_filters])
filtered_qs = [emp for emp in employee_lids if emp in qs]
  

Однако я думаю, что таким образом снижение производительности было бы еще хуже.

Какой самый лучший / быстрый способ сделать это? Спасибо.

Ответ №1:

Эмпирическое правило заключается в том, чтобы фильтровать как можно больше через SQL, поэтому я бы выбрал

 qs = Employee.objects.filter(id__in=[emp.id for emp in employee_list], [other_filters])
  

У меня нет никакого тестирования производительности, чтобы подтвердить это.

Комментарии:

1. Могу отметить, что это сильно зависит от размера как набора запросов, так и списка и варианта использования

Ответ №2:

Как отметил Martol1ni, вы хотите фильтровать на уровне SQL, когда это возможно, поэтому я думаю, что ваши методы становятся все медленнее, но это другая проблема…

На основе документов Django:https://docs.djangoproject.com/en/dev/ref/models/querysets/ Я думаю, что у вас id__in должен быть список целых идентификаторов, а не список моделей.

Редактировать: О, я вижу, что он рассмотрел это в своем ответе, но не было ясно, что это неверно в вашем вопросе.

Правка2: Но да, если вы хотите знать наверняка, что действительно важно, так это реальная производительность, которую вы можете достичь с помощью django-debug-toolbar. Мне кажется, что реальной проблемой было id__in неправильное использование, которое привело вас к поиску более сложных способов сделать то, что вы хотели сделать.

Комментарии:

1. Я запустил профилировщик для каждого из разных методов, но не увидел слишком большой разницы между ними. Очевидно, что мой набор тестовых данных намного меньше, чем производственный, но построение списка идентификаторов из списка объектов, а затем фильтрация id__в id_list казались самыми быстрыми.