Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django Filter Consolidate data using Aggregate

I want to populate dynamic data using Django Filter Date Range, I have achieved this. In this there is a consolidated data which I am collecting of a single column, which is also working using aggregate. Now I want the consolidated to change as per the records which gets selected when date range is applied in Django filter form.

I am able to consolidate data in the column and get a total out of it in “manual_total” [when I pre-define the date field]. But when I filter using the Django Filter Date range field using Form and filters, I am not getting total as per the columns being fetched. How do I achieve it?

When I filter as per date in the form, the total should be as per the records showing post filter. For example, I have 2 records from March 1st to March 31st and 1 record for April 1st. If I filter March 1st to 31st, it shows only total of 2 records, but total it shows including the 3rd record. Below are my code and pls guide me to join the queryset and aggregate together to retrieve data as per the date range filter I select.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

models.py

class Event(models.Model):
    name = models.CharField(max_length=255, null=True)
    event_date = models.DateField(default=None, null=True)
    event_price = models.IntegerField(null=True)

    def __str__(self):
        return self.name

views.py

from django.db.models import Sum

def viewEvent(request):
    event = Event.objects.all()
    manual_total = Event.objects.filter(event_date__range=["2024-03-01", "2024-03-30"]).aggregate(TOTAL=Sum('event_price'))['TOTAL']
    eventFilter = EventFilter(request.GET, queryset=event)
    event = eventFilter.qs
    total = Event.objects.aggregate(TOTAL=Sum('event_price'))['TOTAL']
    context = {'event': event, 'manual_total: manual_total', 'eventFilter': eventFilter}
    return render(request, 'view_event.html', context)

forms.py

class EventForm(forms.ModelForm):
    class Meta:
        model = Event
        fields = '__all__'
        widgets = {
            'event_date': DateInput(),

filters.py

class EventFilter(django_filters.FilterSet):
    start_date = DateFilter(field_name="event_date", lookup_expr='gte', widget=DateInput(attrs={'type': 'date'}))
    end_date = DateFilter(field_name="event_date", lookup_expr='lte', widget=DateInput(attrs={'type': 'date'}))
    total = Event.objects.aggregate(TOTAL=Sum('event_price'))['TOTAL']

    class Meta:
        model = Event
        fields = 'event_date', 'event_price'

view_event.html

{% extends 'base.html' %}
{% load static %}
{% block content %}

<br>

<div style="width:1400px; margin:0 auto;" class="row">
    <div class="col-md-8">
        <div class="card card-body">
            <h5>&nbsp; Event Report :</h5>
            <div class="row">
    <div class="col">
        <div class="card card-body">
            <form method="get">
                Event Date (Start): {{ eventFilter.form.start_date }}
                Event Date (End):{{ eventFilter.form.end_date }}

                <button class="btn btn-primary" type="submit">Filter</button>
            </form>
        </div>
    </div>
</div>
           <div class="card card-body">
      <table class="table table-sm">
        <tr>
          <th>Event Name</th>
          <th>Event Date</th>
          <th>Event Price</th>
        </tr>
        {% for items in event %}
        <tr>
          <td>{{ items.name }}</td>
          <td>{{ items.event_date }}</td>
            <td>{{ items.event_price }}</td>
          {% endfor %}
        </tr>
      </table>
              <table class="table table-sm">
        <tr>
          <th></th>
            <th></th>
            <th></th>
            <th></th>
          <th>TOTAL: {{ total }}</th>

        </tr>
              </table>
    </div>

        </div>

    </div>

</div>


{% endblock %}

Django Aggregate in Filter queryset

>Solution :

You don’t use the filtered queryset, but the entire queryset. You can work with:

class EventFilter(django_filters.FilterSet):
    start_date = DateFilter(
        field_name='event_date',
        lookup_expr='gte',
        widget=DateInput(attrs={'type': 'date'}),
    )
    end_date = DateFilter(
        field_name='event_date',
        lookup_expr='lte',
        widget=DateInput(attrs={'type': 'date'}),
    )

    @property
    def total(self):
        return self.qs.aggregate(TOTAL=Sum('event_price'))['TOTAL']

    class Meta:
        model = Event
        fields = 'event_date', 'event_price'

and then render with:

 <th>TOTAL: {{ eventFilter.total }}</th>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading