Ok, hay una forma de hacerlo, que implica agregar un par de nuevas etiquetas de plantilla y extender las plantillas de administración.
En primer lugar, en la carpeta de su aplicación templatetags
, se crea un archivo admin_totals.py
que contiene una etiqueta de plantilla para crear una línea de totales:
from django.template import Library
register = Library()
def totals_row(cl):
total_functions = getattr(cl.model_admin, 'total_functions', {})
totals = []
for field_name in cl.list_display:
if field_name in total_functions:
values = [getattr(i, field_name) for i in cl.result_list]
totals.append(total_functions[field_name](values))
else:
totals.append('')
return {'cl': cl, 'totals_row': totals}
totals_row = register.inclusion_tag("myapp/totals_row.html")(totals_row)
entonces usted necesita la plantilla para dicha fila en myapp/totals_row.html
(donde quiera que sus plantillas están):
<table id="result_totals">
<tfoot>
<tr>
{% for total in totals_row %}<td>{{ total }}</td>{% endfor %}
</tr>
</tfoot>
</table>
Luego hay que cablear que en una plantilla de administración personalizada que hereda de forma predeterminada de Django, como myapp/mymodel_admin.html
:
{% extends "admin/change_list.html" %}
{% load admin_totals %}
{% block result_list %}
{{ block.super }}
{% totals_row cl %}
{% endblock %}
Por último, se cablea que en la configuración en el archivo de admin.py
en su aplicación:
class MyModelAdmin(ModelAdmin):
list_display = ('name', 'date', 'numerical_awesomeness')
total_functions = {'numerical_awesomeness': sum}
change_list_template = 'myapp/mymodel_admin.html'
Eso debería alambre en la plantilla de administración personalizado para su nuevo modelo, que muestra la fila de totales. También puede ampliarlo con otras funciones de resumen que no sean sum
, si lo desea.
Un pequeño punto a la izquierda: la fila de totales no está realmente en la tabla de resultados, porque eso requeriría una cierta copia y pegado de las plantillas de administración de Django. Para los puntos de bonificación, se puede añadir en el siguiente pizca de JavaScript para la parte inferior de su totals_row.html
archivo:
<script type="text/javascript">
django.jQuery('#result_list').append(django.jQuery('#result_totals tfoot')[0])
django.jQuery('#result_totals').remove()
</script>
Una advertencia: todo esto solo reflejan los totales de los elementos que se muestran actualmente, en lugar de para todos los elementos existencia. Una forma de evitar esto es establecer list_per_page
en un número inadmisiblemente grande en su clase ModelAdmin
, si no le importa el posible golpe de rendimiento.
Solo para asegurarte: ¿Te refieres a la suma total de todos los objetos _en la página actual_ o _todos los objetos en la base de datos_? –
@lazerscience: me refiero a los objetos que se muestran actualmente (por lo que si aplica un filtro solo mostrará los elementos filtrados) – Claudiu