Django Filter Консолидация данных с помощью агрегата

Я хочу заполнить динамические данные с помощью Django Filter Date Range, мне это удалось. При этом есть консолидированные данные, которые я собираю из одного столбца, который также работает с использованием агрегата. Теперь я хочу, чтобы консолидированные данные менялись в зависимости от записей, которые выбираются при применении диапазона дат в форме фильтра Django.

Я могу объединить данные в столбце и получить из них итог в "manual_total" [когда я предварительно определяю поле даты]. Но когда я фильтрую с помощью поля Django Filter Date range, используя Form и фильтры, я не получаю итогов в соответствии с получаемыми столбцами. Как мне этого добиться?

Когда я фильтрую по дате в форме, итог должен соответствовать записям, отображаемым после фильтра. Например, у меня есть 2 записи с 1 марта по 31 марта и 1 запись за 1 апреля. Если я отфильтровываю с 1 по 31 марта, то отображается только 2 записи, а в сумме - 3 записи. Ниже приведен мой код, и, пожалуйста, подскажите мне, как объединить наборы запросов и агрегировать их, чтобы получить данные в соответствии с выбранным фильтром диапазона дат.

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

Вы используете не отфильтрованный набор запросов, а весь набор. Вы можете работать с:

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'

и затем выполните рендеринг с помощью:

 <th>TOTAL: {{ eventFilter.total }}</th>
Вернуться на верх