Django: annotate Sum Case When depending on the status of a field

前端 未结 2 897
独厮守ぢ
独厮守ぢ 2021-02-09 15:43

In my application i need to get all transactions per day for the last 30 days.

In transactions model i have a currency field and i want to convert the value in euro if

相关标签:
2条回答
  • 2021-02-09 16:29

    The only thing that remains is an order_by. This will (yeah, I know that sounds strange), force Django to perform a GROUP BY. So it should be rewritten to:

    queryset = Transaction.objects.filter(
        created__gte=last_month,
        status=Transaction.COMPLETED
    ).extra(
        {"date": "date_trunc('day', created)"}
    ).values(
        'date'
    ).annotate(
        amount=Sum(Case(
            When(currency=Core.CURRENCY_EUR, then='amount'), 
            When(currency=Core.CURRENCY_USD, then=F('amount') * 0.8662), 
            When(currency=Core.CURRENCY_GBP, then=F('amount') * 1.1413),
            default=0,
            output_field=FloatField()
        ))
    ).order_by('date')

    (I here fixed the formatting a bit to make it more readable, especially for small screens, but it is (if we ignore spacing) the same as in the question, except for .order_by(..) of course.)

    0 讨论(0)
  • 2021-02-09 16:33

    We need to aggregate the query set to accomplish what you are trying.

    Try using aggregate()

    queryset = Transaction.objects.filter(created__gte=last_month, status=Transaction.COMPLETED).extra({"date": "date_trunc('day', created)"}).values('date').aggregate(
    amount=Sum(Case(When(currency=Core.CURRENCY_EUR, then='amount'), 
                    When(currency=Core.CURRENCY_USD, then=F('amount') * 0.8662), 
                    When(currency=Core.CURRENCY_GBP, then=F('amount') * 1.1413), default=0, output_field=FloatField())))
    

    for more info: aggregate()

    0 讨论(0)
提交回复
热议问题