Я пытаюсь получить оставшиеся OrderLines указанного c Order, который еще можно вернуть.
Поэтому для каждой OrderLine ордера я хочу вычислить сумму числа атрибут всех существующих RefundedLine, ссылающихся на строку заказа.
Затем эту сумму сравнивают с атрибутом NumberLine : если оно равно, строка больше не может быть возвращена, если она меньше он может быть возвращен (sum(RefundedLine number) < OrderLine number
).
(может быть несколько RefundedLine, ссылающихся на OrderLine, поскольку ордер может иметь отдельный возврат до полного возмещения).
Вот мои модели:
class Order(models.Model):
pass
class OrderLine(models.Model):
order = models.ForeignKey(Order,
on_delete=models.CASCADE,
related_name="order_lines")
number = models.SmallIntegerField(default=1,
validators=[MinValueValidator(1)])
class Refund(models.Model):
""" Is attached to one order, can concern multiples lines """
order = models.ForeignKey(Order, on_delete=models.PROTECT, editable=False)
lines = models.ManyToManyField(OrderLine, through='RefundedLine')
class RefundedLine(models.Model):
""" Used for m2m """
refund = models.ForeignKey(Refund, on_delete=models.CASCADE)
line = models.ForeignKey(OrderLine, on_delete=models.PROTECT)
number = models.SmallIntegerField(default=1,
validators=[MinValueValidator(1)])
Теперь мои попытки и их ошибки:
Попытка 1:
return OrderLine.objects.filter(order=self.order_id,
number__lt=Sum(Subquery(
RefundedLine.objects.filter(line=OuterRef('pk')).values('number')
)))
ОШИБКА: должен появиться столбец «cart_orderline.id» в предложении GROUP BY или должен использоваться в статистической функции LINE 1: SELECT "cart_orderline". "id", "cart_orderline". "order_id", "...
Ошибка сообщение не является точным, так как оно было переведено себя
Попытка 2:
Из Django do c сама , нет ошибки, но не работает, как ожидалось. Если у OrderLine нет RefundedLine, ссылающегося на него, я получаю пустой набор запросов, в то время как он должен вернуть OrderLine.
refunded_lines = RefundedLine.objects.filter(line=OuterRef('pk')).order_by().values('line')
total_refunded_lines = refunded_lines.annotate(total=Sum('number')).values('total')
refundable_lines = OrderLine.objects.filter(number__gt=Subquery(total_refunded_lines))
Попытка 3:
refunded_lines = RefundedLine.objects.filter(line=OuterRef('pk')).order_by().values('line')
total_refunded_lines = refunded_lines.annotate(total=Sum('number', output_field=models.IntegerField())).values('total')
refundable_lines = OrderLine.objects\
.filter(order=self.order_id)\
.annotate(refundable_number=Case(
When(
Exists(total_refunded_lines),
then=Value(total_refunded_lines[:1]),
),
default=Value(0),
output_field=models.IntegerField()
)).filter(refundable_number__gt=0)
Сообщение об ошибке:
django .db.utils.ProgrammingError: невозможно адаптировать тип 'QuerySet'
Когда я пытаюсь сделать l oop более refunded_lines
.
У меня есть другие попытки, но я не думаю, что написание их было бы полезным, поскольку пост уже сгруппирован.