在django聚合中使用ifnull default

问题描述 投票:1回答:1

我有以下模型类:

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

class InRecord(models.Model):
    goods = models.ForeignKey(Goods, related_name='in_records')
    timestamp = models.DateTimeField()
    quantity = models.IntegerField()

class OutRecord(models.Model):
    goods = models.ForeignKey(Goods, related_name='out_records')
    timestamp = models.DateTimeField()
    quantity = models.IntegerField()

所以,我想得到一个QuerySet,其中包含所有具有正存储库的商品。

另一种描述它的方法是,我想过滤具有比OutRecord摘要更大的InRecord数量摘要的商品。


What I've tried:

首先,我使用annotate将摘要添加到查询集:

qs = Goods.objects.annotate(
        qty_in=Sum(in_records__quantity), 
        qty_out=Sum(out_records_quantity)
    )

这似乎有效,但有一个问题,当某些商品没有相对的in_records或out_records时,注释的字段返回None。

问:那么,在这种情况下,有没有办法让我设置默认值,就像在sql中调用ifnull(max(inreocrd.quantity), 0) *一样?


在此之后,我想在该QuerySet上添加一个过滤器:

我试过了:

qs = qs.filter(qty_in__gt(F(qty_out)))

但是,如果货物上没有记录,它就不起作用。

请帮忙。

django default aggregate models annotate
1个回答
3
投票

你可以使用Django的Coalesce函数。这样的东西应该在Django 1.8或更高版本中工作:

from django.db.models.functions import Coalesce

qs = Goods.objects.annotate(
        qty_in=Sum(Coalesce(in_records__quantity, 0)),
        qty_out=Sum(Coalesce(out_records__quantity, 0))
    )
© www.soinside.com 2019 - 2024. All rights reserved.