django - annotate() - 对另一列进行过滤的列的 Sum()

标签 django listview django-annotate

我有以下两个型号。

class Product(models.Model):
    product_group=models.ForeignKey('productgroup.ProductGroup', null=False,blank=False)
    manufacturer=models.ForeignKey(Manufacturer, null=False,blank=False)
    opening_stock=models.PositiveIntegerField(default=0)

    class Meta:
        unique_together = ('product_group', 'manufacturer')

TRANSACTION_TYPE=(('I','Stock In'),('O','Stock Out'))
class Stock(models.Model):
    product=models.ForeignKey('product.Product', blank=False,null=False)
    date=models.DateField(blank=False, null=False,)
    quantity=models.PositiveIntegerField(blank=False, null=False)
    ttype=models.CharField(max_length=1,verbose_name="Transaction type",choices=TRANSACTION_TYPE, blank=False)

我需要列出具有 stock_in_sum=Sum(of all stock ins)stock_out_sum=Sum(of all stock outs)blance_stock=opening_stock 的所有产品+stock_in_sum - stock_out_sum

这就是我迄今为止所取得的成就。

class ProductList(ListView):
    model=Product

    def get_queryset(self):
        queryset = super(ProductList, self).get_queryset()
        queryset = queryset.prefetch_related('product_group','product_group__category','manufacturer')
        queryset = queryset.annotate(stock_in_sum = Sum('stock__quantity'))
        queryset = queryset.annotate(stock_out_sum = Sum('stock__quantity'))

我需要得到

  1. stock_in_sum 作为 sum(quantity),其中 ttype='I'
  2. stock_out_sum 作为 sum(quantity),其中 ttype='O'
  3. blance_stockproduct.opening_stock + stock_in_sum - stock_out_sum

以及每个 Product 对象。

如何实现这一目标?

谢谢。

最佳答案

您可以使用conditional aggregation

queryset = queryset.annotate(
    stock_in_sum = Sum(Case(When(stock__ttype='I', then=F('stock__quantity')), output_field=DecimalField(), default=0)),
    stock_out_sum = Sum(Case(When(stock__ttype='O', then=F('stock__quantity')), output_field=DecimalField(), default=0)))
)

求和,然后用 F() expression 计算余额

queryset = queryset.annotate(balance_stock=F('opening_stock') + F('stock_in_sum') - F('stock_out_sum'))

您还可以链接不同的操作而不是多次分配:

queryset = queryset.prefetch_related(...).annotate(...).annotate(...)

关于django - annotate() - 对另一列进行过滤的列的 Sum(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45506898/

相关文章:

java - 当设备在 Android 中水平放置时,为什么 ListView 内的嵌套自定义 View 会阻止正确聚焦?

javascript - 如何将样式更新到 jquery mobile 中的 ListView ?

css - 无法识别 django css 文件 - 配置错误?

javascript - Django:如何使用模板从静态文件加载 javascript

python - 在可浏览的 api_root 中混合 View 和 ViewSet

python - Django 查询集优化 - 防止选择带注释的字段

python - DeleteView 有 2 个争论帖子和用户

c# - ListView 条件分组

django - 针对 django graphene 上的 graphql 查询返回带注释的查询集