Все операции над набором запросов, такие как .filter()
, являются символическими, пока набор запросов не будет перечислен.Затем SQL-запрос компилируется и выполняется.Неэффективно вычислять запас по большому нефильтрованному набору запросов, а затем даже запускать его снова с фильтрацией.Вы можете разделить фильтр на условия, не связанные с запасом, добавленным к набору запросов, а затем фильтр, связанный с запасом, который вы оцениваете в том же цикле Python, где вы вычисляете запас.
result = []
for product in queryset_products.filter(**simple filters):
product.stock = some_stock_calc...
if product.stock > 0 or not required_on_stock:
result append(product)
Поле кэша возможных активныхпродукты, которые могут быть на складе, очень полезны для первого простого фильтра.
Возможно, расчет запаса не сложнее, чем, например, запас в полночь плюс сумма операций с запасами с полуночи.Затем текущий запас можно рассчитать с помощью Subquery
в аннотации и отфильтровать вместе.Он будет скомпилирован в один SQL-запрос с основным запросом с присоединениями к связанным моделям и относительно простым подзапросом для акций.(Это был бы другой вопрос.)