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> 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>