Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Group_By e Sum no Django

Já andei pesquisando e testando algumas coisas e não está gerando o resultado desejado. Tenho um modelo de Pagamentos no meu banco de dados. Ele puxa do banco todas as matrículas que estão vinculados a uma data de pagamento que eu vou filtrar. Por exemplo: no meu filtro eu escolho dia 05/06/2020... Dessa forma ele me traz todos os alunos que tem cadastrada a data de pagamento para dia 5. Entretanto, o mesmo aluno pode aparecer em varias matriculas ( e cursos diferentes)... Gostaria de fazer um agrupamento por aluno e somar o valor de mensalidade de cada curso referente àquele aluno. Tentei usar seguinte, mas meu retorno foi a soma da mensalidade de todos os alunos e não por aluno. O problema é que o distinct não funciona junto com o aggregate e gostaria de gerar uma outra tabela a partir disso:

def form_pagamentos(request):
    if request.user.is_authenticated:
        if request.method=='POST':
            data_vencimento_pagamentos=request.POST['data_vencimento_pagamentos']


            date_time_obj = datetime.strptime(str(data_vencimento_pagamentos), '%Y-%m-%d') 

            dia=date_time_obj.day

            matriculas= Matricula.objects.filter(identificador_usuario=request.user.id).filter(alunos__dia_pagamento=dia).aggregate(total_a_receber=Sum('curso__valor_mensalidade_curso'),min_a_receber=Min('curso__valor_mensalidade_curso'))
            dados={
                'title':'Tabela de Pagamentos',
                'data_vencimento':data_vencimento_pagamentos,
                'matriculas':matriculas,
                'perfil':get_object_or_404(PerfilUsuario,identificador_usuario=request.user.id),
            }

            print(matriculas)
2 respostas
solução!

Faaala Raul, como você está?

A cláusula aggregate retorna um dicionário Python, o que significa que você não pode anexar nenhum método queryset, por isso não foi possível encadear o distinct. Além disso, ela sempre retornará um único resultado.

Abaixo, um exemplo de código com o uso do aggegate para agregar por cada item de uma determinada coluna:

from django.db.models import Sum, Min
for country in Country.objects.all():
    result = City.objects.filter(country=country).aggregate(Sum(‘population’))
    print ‘{}: {}’.format(country.name, result[‘population__sum’])

# Output:
# -------
# Brazil: 38676123
# Turkey: 19527090
# Italy: 8589190
# Bangladesh: 17151925
# ...

Porém, a melhor maneira de fazer isso é usando annotate, onde conseguimos agrupar pelo nome da coluna do banco de dados e aplicar algum tipo de operação, seja de soma, média, mínimo, dentre outros. Veja abaixo um código de referência do resultado desse método annotate e a forma que o ORM está realizando essa consulta no banco de dados:

result = Alunos.objects.values(‘matricula’).annotate(Sum(‘curso__valor_mensalidade_curso’))
print(str(result.query))

O código acima é apenas uma referência, para que você tenha uma ideia de uso. Se quiser, você pode disponibilizar seu código conosco no Drive ou Git, assim podemos te dar um feedback direcionado. Além disso, se quiser ler mais sobre esse assunto, sugiro este artigo.

Qualquer dúvida estou por aqui, tá bom?

Grande abraço!

Estou bem, como sempre estudando muito pra entrar no mercado rsrs. Agradeço a resposta, já está anotada. Abraço!