繁体   English   中英

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

[英]Calculate two values and calculate difference in percentage in Django

我的在线营销部门上传了我们营销计划的分析统计数据,我们一直在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>
...

截图 在此输入图像描述

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


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 ,要么像在add_color那样在模板标记中禁用add_color

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM