Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.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 ORM注释总和计算错误,并将其乘以条目数,这是有线的_Django_Django Models_Django Rest Framework_Django Orm - Fatal编程技术网

Django ORM注释总和计算错误,并将其乘以条目数,这是有线的

Django ORM注释总和计算错误,并将其乘以条目数,这是有线的,django,django-models,django-rest-framework,django-orm,Django,Django Models,Django Rest Framework,Django Orm,我正在经历Django ORM的一个有线情况。它返回了一个错误的总和计算,意外地,它乘以了我不想要的条目数,它的行为完全是有线的 这些是我的模型 class Person(models.Model): name = models.CharField(max_length=100) class Purchase(models.Model): person = models.ForeignKey( Person, on_delete=models

我正在经历Django ORM的一个有线情况。它返回了一个错误的总和计算,意外地,它乘以了我不想要的条目数,它的行为完全是有线的

这些是我的模型

class Person(models.Model):
    name = models.CharField(max_length=100)



class Purchase(models.Model):
    person = models.ForeignKey(
        Person,
        on_delete=models.CASCADE,
        related_name='person_purchase'
    )

    amount = models.DecimalField(decimal_places=2, max_digits=5)



class Consumption(models.Model):
    person = models.ForeignKey(
        Person,
        on_delete=models.CASCADE,
        related_name='person_consumption'
    )

    amount = models.DecimalField(decimal_places=2, max_digits=5)
这是我的疑问:

person_wise_payable = Person.objects.annotate(
            difference=ExpressionWrapper(
                Coalesce(Sum('person_purchase__amount'), Value(0)) - Coalesce(Sum('person_consumption__amount'), Value(0)),
                output_field=FloatField()
            ),
        )

    for i in person_wise_payable:
        print(i.difference, i.name)
我试图找出明智的购买和消费之间的区别

例如,我有3个人,foo,doe,jhon

这是他们的作品

你看上面

foo total purchase is 5
doe total purchase is 8
jhon total purchase is 0 (coz, no entry of him)

因此,如果我们从购买中减去消费,则预期产出/差异

我希望你明白我想做什么以及预期的产出

foo 0, doe 6 and jhon -2
但问题是,我当前的查询没有像上面这样返回输出,它返回的是非常有线的,请参见下面的有线结果

-2.0 jhon
10.0 doe
10.0 foo

有人能帮我吗?我怎样才能把它做好?在过去的几天里,我一直在努力解决这个问题,但还不能做到这一点

如果您进行多个连接,那么它们就像一个乘数,因为您进行了查询

SELECT SUM(purchase.amount) - SUM(consumption.amount)
FROM person
LEFT OUTER JOIN purchase
LEFT OUTER JOIN consumption
因此,当存在相关消费时,相同的purchase.amount会重复多次,而当存在相关购买时,相同的consump.amount会重复多次

您可以通过子查询解决此问题,例如:

person_wise_payable = Person.objects.annotate(
    difference=Coalesce(Subquery(
        Purchase.objects.filter(
            person=OuterRef('pk')
        ).values('person').annotate(
            sum=Sum('amount')
        ).values('sum')[:1]
    ), Value(0)) - Coalesce(Subquery(
        Consumption.objects.filter(
            person=OuterRef('pk')
        ).values('person').annotate(
            sum=Sum('amount')
        ).values('sum')[:1]
    ), Value(0))
)

如果进行多个联接,它们就起到了倍增的作用,因为进行查询时,会从某个表左外联接中选择SUMsome列另一个表左外联接,所以该some列会重复。确切地说,为什么首先需要两个模型?也许你可以制作一个模型,其中一个购买量为正数,一个消费量为负数?我想保留两个模型用于购买和消费,因为在我的业务逻辑中,消费也有不同的用例,我想要两个模型,反正我想你的意思是奇怪,而不是有线lol。
-2.0 jhon
10.0 doe
10.0 foo
SELECT SUM(purchase.amount) - SUM(consumption.amount)
FROM person
LEFT OUTER JOIN purchase
LEFT OUTER JOIN consumption
person_wise_payable = Person.objects.annotate(
    difference=Coalesce(Subquery(
        Purchase.objects.filter(
            person=OuterRef('pk')
        ).values('person').annotate(
            sum=Sum('amount')
        ).values('sum')[:1]
    ), Value(0)) - Coalesce(Subquery(
        Consumption.objects.filter(
            person=OuterRef('pk')
        ).values('person').annotate(
            sum=Sum('amount')
        ).values('sum')[:1]
    ), Value(0))
)