It is possible to add the total columns from django so that, for example, it brings me the total of all sales but ignores the pagination when adding the values.
This is my model:
class Venta(models.Model):
cliente = models.CharField(max_length=300, verbose_name='Cliente')
fecha = models.DateField(auto_now_add=True)
descripcion = models.CharField(max_length=300, blank=True, verbose_name='Detalle del pedido')
total = models.DecimalField(decimal_places=2, max_digits=7, verbose_name='Total de la venta')
def __str__(self):
return '{}'.format(self.id)
The filters I made with the django-filter library
class VentasFilter(django_filters.FilterSet):
min_date = django_filters.DateFilter(name="fecha", lookup_expr='gte')
max_date = django_filters.DateFilter(name="fecha", lookup_expr='lte')
min_total = django_filters.NumberFilter(name="total", lookup_expr='gte')
max_total = django_filters.NumberFilter(name="total", lookup_expr='lte')
class Meta:
model = Venta
fields = ['cliente','min_date', 'max_date','min_total','max_total']
And here the view of the sales list:
def filterVenta(request):
venta_list = Venta.objects.all().order_by('-id')
venta_filter = VentasFilter(request.GET, queryset=venta_list)
venta_list = venta_filter.qs
paginator = Paginator(venta_list,10)
page = request.GET.get('page')
try:
ventas = paginator.page(page)
except PageNotAnInteger:
ventas = paginator.page(1)
except EmptyPage:
ventas = paginator.page(paginator.num_pages)
return render(request, 'venta/venta_filter.html', {'filter': venta_filter,'ventas': ventas})
With which I have no problem but I would like to add all the totals but it does not recognize the pagination , that is, if there are 100 sales, it should bring me the total of the 100 sales and not only the total of the 10 that are in the pagination and the same way when there is a filter that brings me the total of all those sales of the filter.
Previously when I didn't have pagination I did it from the client with jquery but now that I have pagination I need to do the sum from the backend (django).
Here is my template where I did the sum but with jquery in case it helps someone:
{% extends 'base/base.html' %}
{% load widget_tweaks %}
{% block titulo %}Filtros de ventas{% endblock %}
{% block contenido %}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'venta:venta_crear' %}">Registrar venta</a></li>
<li class="breadcrumb-item active" aria-current="page">Ventas</li>
</ol>
</nav>
<form method="get">
<div class="spaceFilter">
<div class="card border-info">
<div class="card-body">
<h5 class="font-weight-bold">Filtros de ventas:</h5>
<div class="row">
<div class="form-group col-sm-4 col-md-3">
<label for="cliente"><i class="fa fa-user"></i> Cliente: </label>
{% render_field filter.form.cliente class="form-control" %}
</div>
</div>
<div class="row">
<div class="form-group col-xs-6 col-sm-3 col-md-3">
<label for="desdeDate"><i class="fa fa-calendar"></i> Desde: </label>
{% render_field filter.form.min_date class="form-control" %}
</div>
<div class="form-group col-xs-6 col-sm-3 col-md-3">
<label for="hastaDate"><i class="fa fa-calendar"></i> Hasta: </label>
{% render_field filter.form.max_date class="form-control" %}
</div>
<div class="form-group col-xs-6 col-sm-3 col-md-3">
<label for="desdeMonto"><i class="fa fa-dollar"></i> Monto desde: </label>
{% render_field filter.form.min_total class="form-control" %}
</div>
<div class="form-group col-xs-6 col-sm-3 col-md-3">
<label for="hastaMonto"><i class="fa fa-dollar"></i> Monto hasta: </label>
{% render_field filter.form.max_total class="form-control" %}
</div>
</div>
<div class="col-md-4 offset-md-4">
<button type="submit" class="btn btn-primary btn-block btn-md">
<span><i class="fa fa-filter"></i></span> Filtrar
</button>
</div>
</div>
</div>
</div>
</form>
<div class="table-responsive-md">
<table class="table table-striped" id="tabla-today">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Fecha de venta</th>
<th scope="col">Cliente</th>
<th scope="col">Descripción del pedido</th>
<th scope="col">Total de la venta</th>
<th scope="col">Acciones</th>
</tr>
</thead>
<tbody>
{% for venta in ventas %}
<tr>
<td>{{ venta.id }}</td>
<td>{{ venta.fecha}}</td>
<td>{{ venta.cliente }}</td>
<td>{{ venta.descripcion }}</td>
<td><span class="total-list">{{ venta.total }}</span></td>
<td><a href="{% url 'venta:venta_editar' venta.id %}"><i class="fa fa-eye fa-lg spaceIcon" style="color:#007bff"></i></a>
<a href="{% url 'venta:venta_eliminar' venta.id %}"><i class="fa fa-trash fa-lg colorDnicos"></i></a>
</td></td>
</tr>
{% empty %}
<tr>
<td colspan="8" class="text-center colorVacio">No existen ventas</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<span class="current">
Pagina <span class="colorDnicos">{{ ventas.number }}</span> de
<span class="colorDnicos">{{ ventas.paginator.num_pages }}</span>.
</span>
<ul class="pagination justify-content-center">
{% if ventas.has_previous %}
<li class="page-item"><a class="page-link" href="?page=1">« Inicio</a></li>
<li class="page-item"><a class="page-link" href="?page={{ ventas.previous_page_number }}">Previous</a></li>
{% endif %}
{% for i in ventas.paginator.page_range %}
{% if ventas.number == i %}
<li class="page-item active"><span class="page-link">{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if ventas.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ ventas.next_page_number }}">Next</a></li>
<li class="page-item"><a class="page-link" href="?page={{ ventas.paginator.num_pages }}">Ultimo »</a></li>
{% endif %}
</ul>
<div class="row justify-content-center spaceIndicador">
<div class="card border-info mb-3" style="max-width: 18rem;">
<div class="card-header">Total de ventas</div>
<div class="card-body text-info">
<p class="card-text">EL monto es de: S/.<span class="totalVentas font-weight-bold"></span></p>
</div>
</div>
</div>
{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(document).ready(function(){
$('#id_min_date').datetimepicker({
format: 'DD/MM/YYYY',
locale: 'pe'
});
$('#id_max_date').datetimepicker({
format: 'DD/MM/YYYY',
locale: 'pe'
});
//Calculo de totales
var sum = 0;
$(".total-list").each(function(){
sum += parseFloat($(this).text().replace(',', '.'));
});
$('.totalVentas').text(sum.toFixed(2));
});
</script>
{% endblock %}
Solved (: In case anyone ever needs something like this, here's the solution: simply add to the filter in my function:
and obviously with another variable to be able to send the arguments to the template:
and in the template we can access the total that always puts the name with which you are sending with the arguments and adding __sum:
and remaining as:
I hope it helps someone (:
Update happened to me that if I paged it but when I went to page 2 it removed the filter and the data was thrown again without the filter so I solved it in the following way in the template: