Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 获取每个订单行的可退款项目总数_Django_Postgresql_Django Queryset - Fatal编程技术网

Django 获取每个订单行的可退款项目总数

Django 获取每个订单行的可退款项目总数,django,postgresql,django-queryset,Django,Postgresql,Django Queryset,我正在尝试获取特定订单的剩余订单行,这些订单仍然可以退款 因此,对于订单的每个订单行,我想计算引用该订单行的所有现有退款行的number属性的总和 然后将该金额与订单行编号属性进行比较:如果该金额相等,则该行将无法再退款,如果该金额较小,则可以退款(sum(returnedline number)

我正在尝试获取特定订单的剩余订单行,这些订单仍然可以退款

因此,对于订单的每个订单行,我想计算引用该订单行的所有现有退款行的number属性的总和

然后将该金额与订单行编号属性进行比较:如果该金额相等,则该行将无法再退款,如果该金额较小,则可以退款(
sum(returnedline number)

(可以有多个退款行引用订单行,因为订单可以单独退款,直到完全退款为止)

以下是我的模型:
现在,我的尝试及其错误: 尝试1: 错误:«cart_orderline.id»列必须出现在GROUP BY子句中,或者必须在聚合函数中使用 第1行:选择“购物车订单行”,“id”,“购物车订单行”,“订单id”,“id…”

错误消息并不准确,因为它是我自己翻译的

尝试2: ,没有错误,但无法按预期工作。如果订单行没有引用它的ReturnedLine,则我会得到一个空的queryset,而它应该返回订单行

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: 错误消息:

django.db.utils.ProgrammingError:无法适应类型“QuerySet”

当我尝试循环查看
退款的行时


我还有其他的尝试,但我不认为写它们会有好处,因为这篇文章已经很混乱了。

尝试以下几点:

from django.db.models import Sum, F
OrderLine.objects.filter(
   # do your filtering here if you do not need the annotated value
).annotate(
    refunded_number=Coalesce(Sum('refundedline__number'),0)  # Annotate each OrderLine with the sum of the numbers of its refundedline
).filter(
    number__gt=F('refunded_number')  # Use F() objects to reference a field
)

感谢@GrandPhuba,我可以测试并完成他的答案

# Added the missing filter for the order
refundable_lines= OrderLine.objects.filter(order=self.order_id).annotate(
            # Added Coalesce because if no refundedline exist for the orderline, None will be returned and so the QuerySet will be empty, we do not want that
            refunded_number=Coalesce(Sum('refundedline__number'), 0) 
            # Annotate each OrderLine with the sum of the numbers of its refundedline
        ).filter(
            number__gt=F('refunded_number'),  # Use F() objects to reference a field
        )

谢谢你的快速回答。离我预期的结果不远。1问题,当他们没有退款线路时,我没有退货,因此也没有订单线路。尽管if Sum(‘退款线路号码’)没有。这意味着它可以退款。如何解决?我不明白我们如何引用“ReturnedLine\uuuuu编号”。我的模型中没有设计相关的名称或字段,它不应该是ReturnedLine\uu集吗?最后一件事,它不按顺序过滤,我想我可以在性能注释之前过滤,或者在你的过滤器中过滤?我得到了一个答案无问题的swer(使用合并)。我将回答我自己的问题。非常感谢,我知道一个简单的查询可以满足我的需要。我花了3天时间与求和函数作斗争,并执行子查询,但出现了其他错误…1.我更新了我的答案,以排除订单行,但没有退款行指向它。如果您只想将“无”值更改为零,也可以使用Coalesce。或者你可以合并然后过滤掉零值2.当访问查询中的相关名称时,你只需使用模型名称的小写字母。从模型访问时,你只需使用_set。3.对于过滤,如果你不需要过滤器中的注释字段,你可以在注释之前进行过滤。谢谢你的详细注释!我尝试了upvoting您的答案,并将我的答案标记为已接受(因为它具有与Sum()未返回任何答案的情况相关的相应行为,关于我的初始问题),但它不起作用…(stackoverflow信誉点问题?)无论如何,我得到的比我来的更多。谢谢!编辑:需要等待2天才能接受它,好吧,如果它有帮助的话,我将非常感谢对我的答案的投票:)正如在你的答案的评论中所说的,我尝试了多次,现在它被投票了,我想(至少在我刷新时投票保持不变)在尝试发布此评论时也会出错:(
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)
from django.db.models import Sum, F
OrderLine.objects.filter(
   # do your filtering here if you do not need the annotated value
).annotate(
    refunded_number=Coalesce(Sum('refundedline__number'),0)  # Annotate each OrderLine with the sum of the numbers of its refundedline
).filter(
    number__gt=F('refunded_number')  # Use F() objects to reference a field
)
# Added the missing filter for the order
refundable_lines= OrderLine.objects.filter(order=self.order_id).annotate(
            # Added Coalesce because if no refundedline exist for the orderline, None will be returned and so the QuerySet will be empty, we do not want that
            refunded_number=Coalesce(Sum('refundedline__number'), 0) 
            # Annotate each OrderLine with the sum of the numbers of its refundedline
        ).filter(
            number__gt=F('refunded_number'),  # Use F() objects to reference a field
        )