【问题标题】:Calculate two values and calculate difference in percentage in Django在Django中计算两个值并计算百分比差异
【发布时间】:2016-07-12 18:38:29
【问题描述】:

我的在线营销部门会上传有关我们营销计划的分析统计数据,并且我们一直将记录保存在 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>
...

截图

【问题讨论】:

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


【解决方案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,要么在模板标签中禁用自动转义,就像我在add_color 中所做的那样。

【讨论】:

  • 感谢您的详细帖子。我有点遵循这里的逻辑,但是在实现它时,我在浏览器中收到Could not parse some characters: t_new_sales_2014_wd3|-t_new_sales_2014_wd2| | divide:t_new_sales_2014_wd3 | percent | add_color 错误。我还在学习 Python,所以不确定在哪里识别错误,浏览器错误并没有提供太多线索。
  • 不允许在模板中减去。您可以添加另一个过滤器以进行减法或创建新过滤器。如果你还需要它,我稍后会给你一个过滤器,我现在没有时间。
  • 谢谢,我不久前就知道了。所以我在视图中进行除法,但是在尝试添加 percent 过滤器时,我得到一个 is_number 未定义。我可以直接在模板中添加floatformat:"2",它可以工作,但我宁愿使用percent,这样我可以保持我的模板并从重复代码中查看干净。我会继续努力,但如果您对 is_number 未定义错误有任何线索,那将有所帮助。到目前为止,这个解决方案效果很好,并教会了我一些新技巧。
  • is_number 是我的自定义方法,这就是您收到错误的原因(对不起,我应该提到它)。添加到答案。另外,检查我的第二部分答案,只使用了一个标签。
  • 太棒了!好多了!谢谢。
猜你喜欢
  • 2020-11-27
  • 1970-01-01
  • 2021-06-17
  • 2021-01-05
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多