skip to Main Content

I have created a function to get some date from database, make some calculations and show it in HTML files. However I could not to get just values from views.

def list_pay(request):
    item = Pay.objects.all()

    # Quantidades
    q_total = Pay.objects.all().count
    q_open = Pay.objects.filter(status=0).count
    q_paied = Pay.objects.filter(status=1).count

    # Soma dos valores
    v_total = Pay.objects.aggregate(Sum('value'))
    v_open = Pay.objects.filter(status=0).aggregate(Sum('value'))
    v_paied = Pay.objects.filter(status=1).aggregate(Sum('value'))


    data = {
        'item':item,
        'v_total':v_total,
        'v_open':v_open,
        'v_paied':v_paied,
        'q_total':q_total,
        'q_open':q_open,
        'q_paied':q_paied
        }
        
    return render(request, 'pay/list_pay.html', data)
<div class="row d-flex justify-content-center">
    <h3 class="mb-3 mt-3">Lista <span class="text-success">de pagamentos</span></h3>

    <div class="col m-3 p-3">
        <label>Total de boletos</label>
        <h1 class="text-primary"> {{ q_total }}</h1>
        <h1 class="text-primary"> {{ v_total }}</h1>
    </div>
    <div class="col m-3 p-3">
        <span>Quantidade de boletos</span>
        <h1 class="text-success">{{ q_paied }}</h1>
        <h1 class="text-success">{{ v_paied }}</h1>
    </div>
    <div class="col m-3 p-3">
        <span>Quantidade de boletos</span>
        <h1 class="text-danger">{{ q_open }}</h1>
        <h1 class="text-danger">{{ v_open }}</h1>
    </div>
</div>

The current value loaded = {‘value__sum’: 1831}. The expected output = 1831

I alredy try .values() and transform the dict in a list and other format.

2

Answers


  1. Perform a lookup, so:

    <h1 class="text-success">{{ v_paied.value__sum }}</h1>

    or, you can perform the lookup in the view:

    v_paied = Pay.objects.filter(status=1).aggregate(Sum('value'))['value__sum']

    That being said, you are currently performing multiple queries that can be combined in one SQL query.

    Indeed, we can use:

    from django.db.models import Count, Q, Sum
    
    def list_pay(request):
        data = Pay.objects.aggregate(
            q_total=Count('pk'),
            q_open=Count('pk', filter=Q(status=0)),
            q_paied=Count('pk', filter=Q(status=1)),
            v_total=Sum('value'),
            v_open=Sum('value', filter=Q(status=0)),
            v_paied=Sum('value', filter=Q(status=1)),
        )
        data['item'] = Pay.objects.all()
        return render(request, 'pay/list_pay.html', data)

    So here we make at most two database queries.

    Login or Signup to reply.
  2. You should be able to get all of this in a single aggregate query with something like

    def list_pay(request):
        pay_items = Pay.objects.all()
        aggregate_data = pay_items.aggregate(
            q_open=Count("id", filter=Q(status=0)),
            q_paied=Count("id", filter=Q(status=1)),
            q_total=Count("id"),
            v_open=Sum("value", filter=Q(status=0)),
            v_paied=Sum("value", filter=Q(status=1)),
            v_total=Sum("value"),
        )
    
        data = {
            "item": pay_items,
            **aggregate_data,
        }
    
        return render(request, "pay/list_pay.html", data)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search