在Django模板中进行汇总

3 投票
1 回答
1365 浏览
提问于 2025-04-16 04:21

我在使用Django时,有一个模板,我想要计算每个文档对象最后两列的总和。

{% 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 %}

这一切都是通过以下模型实现的,这些模型为了这个问题进行了简化。

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

最后,抱歉我的英语不好 :)

1 个回答

2

根据我在Django的经验,我觉得在模板里做这些事情并不容易。我通常会选择在视图里进行计算,而不是在模板中。

我的建议是,在视图中计算你需要的两个总和,而不是在模板里。

不过,确实可以在模板中使用一些功能,比如自定义过滤器和标签。使用过滤器的话,可能会像这样:

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

过滤器需要两个参数,一个是你传给过滤器的值,另一个是你可以用来控制它行为的参数。你可以用最后一个参数告诉sum_monto去计算正值或者负值的总和。

这是我随便想出来的一个快速的、未经测试的过滤器实现:

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)

撰写回答