views:

46

answers:

1

I have the following template in django, i want to get the totals of the last 2 columns for each of my document objects

{% for documento in documentos %}
    {% for cuenta in documento.cuentasxdocumento_set.all %}
        <tr {% cycle 'class="gray"' '' %} >
            {% if forloop.first %}
                    <td>{{ documento.fecha_creacion.date }}</td>
                    <td>{{ cuenta.cuenta.nombre }}</td>
                    <td>
                        {% if cuenta.monto >= 0 %}
                            {{ cuenta.monto}}
                        {% endif %}
                    </td>
                    <td>
                        {% if cuenta.monto <= 0 %}
                            {{ cuenta.monto }}
                        {% endif %}
                    </td>
            {% else %}

                    <td colspan="4"></td>
                    <td>{{ cuenta.cuenta.codigo }}</td>
                    <td>{{ cuenta.cuenta.nombre }}</td>
                    <td>
                        {% if cuenta.monto <= 0 %}
                            {{ cuenta.monto }}
                        {% endif %}
                    </td>
                    <td>
                        {% if cuenta.monto >= 0 %}
                            {{ cuenta.monto }}
                        {% endif %}
                    </td>

            {% endif %}
        </tr>
    {% endfor %}
    <tr>
        <td colspan="1"></td>
        <td>Document Total</td>
        <td></td>
        <td></td>
    </tr>
{% endfor %}

This is all done using the following models, which are simplified for the purpose of this question

class Documento(models.Model):
    numero_impreso = models.CharField(max_length=50)
    fecha_creacion = models.DateTimeField(auto_now_add = True)


    cuentas = models.ManyToManyField('CuentaContable', through = 'CuentasXDocumento', null = True)

    def __unicode__(self):
        return self.tipo.nombre + ": " + self.numero_impreso

class CuentasXDocumento(models.Model):
    cuenta = models.ForeignKey('CuentaContable')
    documento = models.ForeignKey('Documento')

    monto = models.DecimalField(max_digits= 14, decimal_places = 6)
    linea = models.IntegerField()

class CuentaContable(models.Model):
    codigo = models.CharField(max_length=50)
    nombre = models.CharField(max_length=100)    
    def __unicode__(self):
        return self.nombre

Finally I'm sorry for the bad english :)

+2  A: 

From my experience with Django, I would say that these things aren't easily done in the template. I try to do my calculations in the view instead of the template.

My recommendation would be to calculate the two sums you need in the view instead of the template.

That beings said, it is possible to do some work in the template using custom filters and tags. Using filters it might look like this:

<td>{% documento.cuentasxdocumento_set.all | sum_monto:"pos" %}</td>
<td>{% documento.cuentasxdocumento_set.all | sum_monto:"neg" %}</td>

Filters take two arguments, the value that you pass to the filter and an argument that you can use to control its behavior. You could use the last argument to tell sum_monto to sum the positive values or the negative values.

This is a quick untested filter implementation off the top of my head:

from django import template

register = template.Library()

@register.filter
def sum_monto(cuentas, op):
    if op == "pos":
         return sum(c.monto for c in cuentas if c.monto > 0)
    else
         return sum(c.monto for c in cuentas if c.monto < 0)
Arlaharen
Thanks, i wouldn't have think of the the filter, i need to do it in the template because it's an arbitrary number of Documentos
armonge
How does an arbitrary number of documents prevent you from calculating the sums in the view?
Arlaharen
I don't know...maybe is because i'm a noob with django and more used to the PHP way of things,
armonge
I mean, in php I would have a temporary variable inside the loop, here i would do my calculations and finally echo....but in the view? here? i just don't know how to
armonge
OK. Perhaps you are there is some confusion on the Django term view? In Django, the view is the piece of code that handles your request and invokes the template. In your case you are probably performing some database query to get your documents. In that same place you could calculate your sums and send them to the template the same way you send your documents.
Arlaharen