Django ORM - добавлять строки в результат, пока SUM('column') не достигнет заданного числа
У меня есть модель, созданная с помощью Django ORM -
class Orders:
units = models.IntegerField(null=False, blank=False)
sell_price_per_unit = models.FloatField(null=True, blank=True)
created_by = models.ForeignKey(User, on_delete=models.PROTECT, null=False, blank=False)
order_status = models.ForeignKey(OrderStatus, on_delete=models.PROTECT, null=False, blank=False)
property = models.ForeignKey(Property, on_delete=models.PROTECT, null=False, blank=False)
order_type = models.ForeignKey(Property, on_delete=models.PROTECT, null=False, blank=False)
...
...
Я хочу написать запрос к select_for_update() и строки должны выбираться до тех пор, пока Sum('sell_price_per_unit') не достигнет заданного числа. Кроме того, я должен применить определенный фильтр и исключить определенные строки на основе условия. filter() & exclude() были довольно простыми, поэтому я уже позаботился об этом, но я понятия не имею, как выбрать строки, пока Sum('sell_price_per_unit') не достигнет заданного числа.
queryset = (
Orders.objects.select_for_update()
.exclude(created_by=created_by)
.values(
"id",
"property",
"units",
"created_by",
"sell_price_per_unit",
"order_status",
)
.filter(
property=order_obj.property,
order_type__name=SELL,
order_status__in=[PARTIALLY_COMPLETED[1], OPEN[1]],
sell_price_per_unit__lte=order_price,
)
.order_by("sell_price_per_unit", "created_at")
)
Возможно ли это осуществить?
Вот SQL решение аналогичной проблемы. Я не уверен, можно ли написать его в DjangoORM.
Итак, вы можете использовать rawSQL для запроса записей.
Но если у вас есть разумное количество записей, вы можете просто отфильтровать их на стороне приложения
queryset = (
Orders.objects.select_for_update()
.exclude(created_by=created_by)
.values(
"id",
"property",
"units",
"created_by",
"sell_price_per_unit",
"order_status",
)
.filter(
property=order_obj.property,
order_type__name=SELL,
order_status__in=[PARTIALLY_COMPLETED[1], OPEN[1]],
sell_price_per_unit__lte=order_price,
)
.order_by("sell_price_per_unit", "created_at")
)
current_sum = 0
orders = []
for order in queryset:
current_sum += order.sell_price_per_unit
if current_sum > threshold:
break
# Do stuff with orders
...