apollos
apollos

Reputation: 323

How Can I sum the Result of a Django Date Range Result in Views

I want to add all the amount field during a date range query search. I have an Income Model with date and amount fields among others. And any time a user select between two dates, I want the amount fields of the query results added as total. Here is what I have tried:

def SearchIncomeRange(request):
    listIncome = Income.objects.all()
    searchForm = IncomeSearchForm(request.POST or None)
    if request.method == 'POST':
       listIncome = Income.objects.filter(
       description__icontains=searchForm['description'].value(),
       date__range=[
                            searchForm['start_date'].value(),
                            searchForm['end_date'].value()
                        ]
    )
   else:
 searchForm = IncomeSearchForm()
 paginator = Paginator(listIncome, 5)
 page = request.GET.get('page')
 paged_income = paginator.get_page(page)
context = {
    
    'searchForm':searchForm,
}

return render(request, 'cashier/search_income_range.html', context)

I am able to get the correct search result but getting the total I don't know how to use the SUM in the above query and pass the total in pagination. So Someone should please help me out. Thanks

Upvotes: 0

Views: 913

Answers (1)

Md Shahbaz Ahmad
Md Shahbaz Ahmad

Reputation: 1166

from django.db.models import Sum

total_amount = listIncome.aggregate(total=Sum('amount'))

where listIncome is your queryset

Edit:

You should pass queryset in pagination with filtered queryset if any filter you apply.

I changed your written code but you can write this code in a good way.

def SearchIncomeRange(request):
    listIncome = Income.objects.all()
    searchForm = IncomeSearchForm(request.POST or None)
    if request.method == 'POST':
        # you can get filter value by your form data
        post_data = request.POST
        description = post_data['description']
        start_date = post_data['start_date']
        end_date = post_data['end_date']
    else:
        # you can get filter value by your query params
        query_params = request.GET
        description = query_params.get('description')
        start_date = query_params.get('start_date')
        end_date = query_params.get('end_date')

    # Apply filter before pagination
    listIncome = listIncome.filter(
                description__icontains=description,
                date__range=[start_date, end_date]
            )
    
    # calculate total_amount 
    total_amount = listIncome.aggregate(total=Sum('amount'))

    paginator = Paginator(listIncome, 5)
    page = request.GET.get('page')
    paged_income = paginator.get_page(page)

    # you can access total_amount in template by passing in context data
    context = {
        'searchForm':searchForm,
        'total_amount': total_amount
    }

return render(request, 'cashier/search_income_range.html', context)

Upvotes: 3

Related Questions