计算两个值并计算Django中的百分比差异

时间:2016-03-25 01:14:16

标签: python django python-3.x django-models django-views

我的在线营销部门上传了有关我们营销计划的分析统计数据,并且我们始终在Excel中保存记录。我已经构建了一个应用程序来替换Excel并突出显示单元格并向其添加功能很容易。我唯一能弄清楚的是如何计算和显示从一个查询到另一个查询的差异。如果我没有正确地提出这个问题,我会道歉,我已经将其作为图片来帮助解释。最后,我想使用一个自定义过滤器,它将知道如何计算类似的对象。我试图弄清楚的所有代码仍然有点过头了。任何协助或推动正确的方向都会很棒。谢谢。

我的观点

t_2014 = traffic.filter(created__year='2014')
...

wd1 = t_2014.filter(created__week_day=1).aggregate(Sum('sessions'), Sum('new_users'), Sum('reminder'), Sum('campaigns'), Sum('new_sales'), Sum('sales_renewals'))
wd2 = t_2014.filter(created__week_day=2).aggregate(Sum('sessions'), Sum('new_users'), Sum('reminder'), Sum('campaigns'), Sum('new_sales'), Sum('sales_renewals'))
...

t_new_sales_2014_wd1 = wd1.get('new_sales__sum')
t_new_sales_2014_wd2 = wd2.get('new_sales__sum')
...

我的模板

<td>{{ t_new_sales_2014_wd1 }}</td>
...
<td>{{ t_new_sales_2014_wd2 }}</td>
...

截图 enter image description here

1 个答案:

答案 0 :(得分:1)

像@brandon所说,你可以创建自定义template tags。 (但是你不应该经常使用它们,这个逻辑应该在视图中,而模板标签会降低页面速度)。 以下是您可能在案例中使用的几个标记:

<强> 1。多个过滤器/标签
我想,首先你需要将两个值分开以获得差异:

@register.filter
def divide(value, arg):
    try:
        return float(value) / float(arg)
    except (TypeError, ZeroDivisionError):
        return None

但您可以使用内置withratio代替自定义代码。 另一个有用的标记/过滤器是percent

@register.filter
def percent(value):
    if not is_number(value):
        return None
    return floatformat(Decimal(value) * Decimal(100.0), 2) + '%'

is_number()是我的自定义代码,用于测试字符串(或数字)是否为数字。

def is_number(s):
    try:
        float(s)
        return True
    except (ValueError, TypeError):
        return False

可能是add_color

@register.filter(needs_autoescape=False)
def add_color(value):
    if float(value) > 0:
        return '<font color="#28a901">%s</font>' % value
    elif float(value) < 0:
        return '<font color="#f63434">%s</font>' % value
    else:
        return str(value)

在模板中只需使用:

{{ t_new_sales_2014_wd1|add:-t_new_sales_2014_wd2|divide:t_new_sales_2014_wd2|percent|add_color }}

但是使用过多的过滤器可能是一个问题,我不能简单地告诉代码做什么。

<强> 2。单个过滤器/标签
也许你应该只创建一个过滤器/标签并使用它。像这样:

@register.filter
def difference(value, arg):
    try:
        result_num = (float(arg) - float(value)) / (float(arg) * 0.01)
        if result_num > 0:
            result = '<font color="#28a901">%s%%</font>' % result_num
        elif result_num < 0:
            result = '<font color="#f63434">%s%%</font>' % result_num
    except (TypeError, ZeroDivisionError):
        return None
    return result

并在模板中使用(替换le作为变量):

{{l|difference:e|safe}}

在模板中使用safe或在模板标记中停用autoescape,就像我在add_color中所做的那样。