【问题标题】:Find Sum of Columns of Data in Django Like and Excel File在 Django Like 和 Excel 文件中查找数据列的总和
【发布时间】:2015-10-20 02:25:03
【问题描述】:

我正在使用 Django 1.8.3 和 Python 3.4.3

将我的问题与 Excel 文件进行比较是解释我的挑战的最佳方式。我有一个在我的模板中显示数据表的 ListView。左列是 1 月到 12 月,顶部有值字段(就像 Excel 电子表格一样)我需要添加“列”的值以呈现“总”和。我已经阅读了几个解决方案,但我似乎无法弄清楚它是一种 Pythonic 方式。

下面是我的代码的 sn-ps,希望能让您对我需要做什么有一个很好的了解。

需要的解决方案:我需要获取每个月 Recipients 表的总值,它将显示在主矩阵中(此处未显示)

感谢您的帮助。如果您有帮助,请同时提供模板标签示例。

index.html(仅显示 1 月和 2 月,但列表到 12 月)

<thead>
  <tr>
    <th></th>
    <th>Quantity</th>
    <th>Recipients</th>
    <th>Unsubscribes</th>
    <th>Bounces</th>
    <th>Open</th>
    <th>Clicks</th>
    <th>Open Rate</th>
    <th>CTR</th>
    <th>Sales</th>
    <th>IFS SignUps</th>
    <th>Traffic</th>
    <th>T/S Ratio</th>
  </tr>
</thead>
<tbody>
  <tr>
    {% if email_list %}
      <td>January</td>
      <td>{{ total_campaigns.January | default_if_none:"0" }}</td>
      <td>{{ total_recipients.January | default_if_none:"0" }}</td>
      <td>{{ total_unsubscribes.January | default_if_none:"0" }}</td>
      <td>{{ total_bounces.January | default_if_none:"0" }}</td>
      <td>{{ total_open.January | default_if_none:"0" }}</td>
      <td>{{ total_clicks.January | default_if_none:"0" }}</td>
      <td>{% average total_open.January total_recipients.January %}</td>
      <td>{% average total_clicks.January total_open.January %}</td>
    {% endif %}
    {% if traffic_list %}
      <td>{{total_sales.January | default_if_none:"0" }}</td>
      <td>{{total_ifs_signups.January | default_if_none:"0" }}</td>
      <td>{{total_traffic.January | default_if_none:"0" }}</td>
      <td>{% ratio total_traffic.January total_sales.January %}</td>
    {% endif %}
  </tr>
  <tr>
    {% if email_list %}
      <td>February</td>
      <td>{{ total_campaigns.February | default_if_none:"0" }}</td>
      <td>{{ total_recipients.February | default_if_none:"0" }}</td>
      <td>{{ total_unsubscribes.February | default_if_none:"0" }}</td>
      <td>{{ total_bounces.February | default_if_none:"0" }}</td>
      <td>{{ total_open.February | default_if_none:"0" }}</td>
      <td>{{ total_clicks.February | default_if_none:"0" }}</td>
      <td>{% average total_open.February total_recipients.February %}</td>
      <td>{% average total_clicks.February total_open.February %}</td>
    {% endif %}
    {% if traffic_list %}
      <td>{{total_sales.February | default_if_none:"0" }}</td>
      <td>{{total_ifs_signups.February | default_if_none:"0" }}</td>
      <td>{{total_traffic.February | default_if_none:"0" }}</td>
      <td>{% ratio total_traffic.February total_sales.February %}</td>
    {% endif %}
  </tr>

  ... ( This repeats through the month of December )

views.py(来自我的视图文件的示例数据)

    class DashboardView(TemplateView):
        template_name = "dashboard/pages/index.html"

        def get_context_data(self, **kwargs):
            context = super(DashboardView, self).get_context_data(**kwargs)
            context['email_list'] = Email.objects.all()
            context['traffic_list'] = Traffic.objects.all()

            days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
            months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',
                      'November', 'December']

            total_campaigns = {}
            campaign_totals = {}
            total_recipients = {}
            total_unsubscribes = {}
            total_bounces = {}
            total_open = {}
            total_clicks = {}
            total_sales = {}
            total_ifs_signups = {}
            total_traffic = {}

            for month in months:
                # total count
                total_campaigns[month] = Email.objects.filter(month=month).count()
                # recipients
                total_recipients[month] = Email.objects.filter(month=month).aggregate(
                    Sum('recipients')).get('recipients__sum', 0.00)
                # unsubscribes
                total_unsubscribes[month] = Email.objects.filter(month=month).aggregate(
                    Sum('unsubscribes')).get('unsubscribes__sum', 0.00)
                # bounces
                total_bounces[month] = Email.objects.filter(month=month).aggregate(Sum('bounces')).get(
                    'bounces__sum', 0.00)
                # opens
                total_open[month] = Email.objects.filter(month=month).aggregate(
                    Sum('open')).get('open__sum', 0.00)
                # clicks
                total_clicks[month] = Email.objects.filter(month=month).aggregate(
                    Sum('clicks')).get('clicks__sum', 0.00)

...

【问题讨论】:

  • 我会建议你与 Pandas 结合使用。
  • 感谢您的参考。当我进入应用程序的第二阶段时,我会仔细研究一下,当我不是一个菜鸟时……Pandas 有点超出我的经验水平 :) 谢谢。
  • 欢迎。其实我会建议你再看看它。这并不像看起来那么困难,而且它肯定会在中长期内为您节省开发时间。在数据分析方面,Pandas 很酷。
  • 当您可以访问包含所有数据的关系数据库时,为什么还需要 Pandas?听起来像是另一个不必要的复杂层。这种事情应该在数据库级别使用聚合来完成。我会使用 SQL。
  • 我想我会再看看 Pandas。昨晚我钻了一点洞,进一步研究它,因为我的应用程序最终会处理许多数据流,所以仔细观察可能是有意义的。

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


【解决方案1】:

Django aggregation 支持这个。

对于按字段分组的聚合,使用 values clauseannotate ,例如:

>>> from django.db.models import Count, Sum

>>> stats = Email.objects.all().values('month').annotate(
        Count('month'), Sum('recipients'), Sum('unsubscribes'), ...)
>>> stats
[{'month': 'January', 'month__count': 100, 'recipients__sum': 24, ... }
 {'month': 'February', 'month__count': 75, 'recipients__sum': 22, ... }]

您也可以使用aggregate从数据库中获取总数:

>>> Email.objects.all().aggregate(
        Count(), Sum('recipients'), Sum('unsubscribes'), ...)

{'id__count': 175, 'recipients__sum': 46, ...}

但是,避免再次查询数据库并根据内存中已有的数据计算总计(按月聚合)可能会更快:

>>> totals = {}
>>> for key in ['month__count', 'recipients__sum', 'unsubscribes__sum', ...]:
...     totals[key] = sum(month.get(key, 0) for month in stats)

【讨论】:

  • 这太好了,谢谢。这是我认为for key in ['month__count', 'recipients__sum', 'unsubscribes__sum']: stats = Email.objects.all().values('month').annotate(Count('month'), Sum('recipients'), Sum('unsubscribes'),) totals[key] = sum(month.get(key, 0) for month in stats) 中的代码这是我的模板标签{{ totals }} 但它呈现了这个......我知道我缺少一些简单的东西{'recipients__sum': 7026255, 'month__count': 44, 'unsubscribes__sum': 7701} 我怎样才能让它呈现收件人的总数?
  • 使用键从totals 字典中获取所需的值,例如:{{ totals.recipients__sum }}
  • 我昨天试过了,但没有用,然后我才意识到总和的双下划线。工作出色!谢谢。
猜你喜欢
  • 2022-12-09
  • 1970-01-01
  • 2023-03-20
  • 2019-12-24
  • 2014-02-19
  • 2021-12-18
  • 2018-03-20
  • 2023-03-21
  • 2013-10-11
相关资源
最近更新 更多