在Django模板中进行汇总
我在使用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)