【问题标题】:Can I Sum up properties in an annotate我可以总结注释中的属性吗
【发布时间】:2019-09-16 20:30:11
【问题描述】:

我正在我的项目中创建一个 html 表,该表由我的数据库中的一些总和值填充,我正在尝试求和 (coins_remaining),这是我的数据库模型的一个属性。 Coins_remaining 是通过从 (amount from Transaction table) 中减去 (sum_amount_sold from Sale table) 来计算的。这可能吗?如果可以,我该怎么做?

下面的 HTML 表格

           {% for transaction in transactions %}
            <tr>
                <td>{{transaction.currency}}</td>
                <td>{{transaction.sum_amount_purchased}}</td>                
                <td>{{transaction.sum_total_price_purchased}}</td>
                <td>{{transaction.sum_total_price_purchased}}</td>
            </tr>
            {% endfor %}

下面的函数

@login_required
def portfolio(request):



    context = {
        'transactions': Transaction.objects.filter(owner=request.user).values('currency').annotate(

            sum_amount_purchased=Sum('amount'),
            sum_total_price_purchased=Sum('total_price')),
            sum_amount_current=?

    }
    return render(request, 'webapp/portfolio.html', context, {'title': 'Portfolio'})

下面的交易模型

class Transaction(models.Model):
    currency = models.CharField(max_length=20)
    amount = models.IntegerField()
    total_price = models.DecimalField(max_digits=8, decimal_places=2)
    date_purchased = models.DateTimeField()
    note = models.TextField(default="")
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    amount_per_coin = models.DecimalField(max_digits=8, decimal_places=2, editable=False)


    def save(self, *args, **kwargs):
        self.amount_per_coin = self.total_price / self.amount
        super(Transaction, self).save(*args, **kwargs)

    def __str__(self):
        return str(self.pk)+','+self.currency + ', '+str(self.amount)

    def get_absolute_url(self):
        return reverse('transaction-detail', kwargs={'pk': self.pk})

    @property
    def coins_remaining(self):
        return self.amount - sum(self.sales.all().values_list('amount_sold', flat=True))

下面的销售模型

class Sale(models.Model):
    amount_sold = models.IntegerField()
    total_price_sold = models.DecimalField(max_digits=8, decimal_places=2)
    date_sold = models.DateTimeField(default=timezone.now)
    note = models.TextField(default="")
    transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE, related_name="sales")
    amount_per_coin_sold = models.DecimalField(max_digits=8, decimal_places=2, editable=False)

    def __str__(self):
        return str(self.pk)+','+str(self.amount_sold) + ', '+self.note

    def save(self, *args, **kwargs):
        self.amount_per_coin_sold = self.total_price_sold / self.amount_sold
        super(Sale, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('sale-detail', kwargs={'pk': self.pk})

【问题讨论】:

    标签: django database orm sum


    【解决方案1】:

    您可以为此使用Subquery注意:您必须使用OuterRef 才能获得正确的Transaction。无法真正尝试,但这就是您可以使用Subquery 注释查询集并在之后的计算中使用它的方法。我不完全确定这是否能解决你的问题,但你去吧:

    coins_remaining_query = (
        Sale.objects.filter(transaction=OuterRef("id"))
        .annotate(coins_remaining=Sum("amount_sold"))
        .values("coins_remaining")
    )
    
    Transaction.objects.filter(owner=request.user).values("currency").annotate(
        sum_amount_purchased=Sum("amount"),
        sum_total_price_purchased=Sum("total_price"),
        coins_remaining=Subquery(coins_remaining_query)
    ).annotate(sum_amount_current=F("sum_amount_purchased")-F("coins_remaining"))
    

    【讨论】:

    • 感谢@jsbeckr,但我正在尝试计算剩余的硬币数量,即 sum_amount_current=F("sum_amount_purchased") - sum(self.sales.all().values_list('amount_sold', flat=True))
    • 抱歉误读了这个问题。我认为您可以为此在Sale 上进行子查询:books.agiliq.com/projects/django-orm-cookbook/en/latest/…
    • 感谢@jsbeckr。你知道我如何将它集成到这段代码中吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 2018-05-11
    • 1970-01-01
    • 2012-01-01
    • 2011-05-08
    • 2016-10-17
    • 1970-01-01
    相关资源
    最近更新 更多