获取MonthSet的查询集和费用金额

时间:2014-11-24 12:32:31

标签: python sql django date group-by

这看起来像一个简单的问题,但我无法获得预期的结果。我有一张这样的桌子:

| id# | Concept | Amount |    Date    |
| ... |   ...   |   10   | 10/12/2013 |
| ... |   ...   |   20   | 12/12/2013 |
| ... |   ...   |   30   | 02/01/2014 |
| ... |   ...   |   40   | 03/01/2014 |
| ... |   ...   |   50   | 04/02/2014 |
| ... |   ...   |   60   | 05/02/2014 |

我想找到一种方法来获取带有此表的QuerySet:

| Date.year | Amount |
|    2013   |    30  |
|    2014   |   180  |

我想我能够以类似的方式获得,例如:

| Date.month | Amount |
|   12/2013  |    30  |
|   01/2014  |    70  |
|   02/2014  |   110  |

有什么想法吗?

修改

我会尽力澄清,抱歉任何误解或错误的解释: - /

我有这个型号:

from django.db import models
from django.core.urlresolvers import reverse

class Expense(models.Model):
    concept = models.CharField(max_length=255)
    date = models.DateField()
    amount = models.DecimalField(max_digits=7,decimal_places=2)

    class Meta:
        ordering = ['date']

    def __unicode__(self):
        return '%s' % (self.concept)

    def get_absolute_url(self):

我有这个模板:

...
<table>
  {% for year in years %}
    <tr>
      <td width="40%">
        {{ year.year }}
      </td>
      <td width="60%" align="right">{{ year.total_amount }}</td>
    </tr>
  {% endfor %}    
</table>
...

我正在尝试为view找到一个QuerySet:

def index(request):
    years = Expense.objects.values('date').annotate(total_amount=Sum('amount'))
    return render(request, 'account/index.html', {'years': years})

在这种情况下,years正在返回一些内容&#34;关闭&#34;到我想要的,因为它按日期对expenses进行分组,但我想按月或年分组,而不是&#34; day&#34;。

我不知道执行此操作的最佳方式是什么,查询费用或模板或其他方式。这就是我需要的。我希望现在有点清楚。

2 个答案:

答案 0 :(得分:0)

这种方法并不完全有效(因为你正在处理python端的数据),尽管这并不是说它无论如何都很慢。对于大多数情况,它应该无缝地工作。

 #view
 def myview(request):
     expenses = Expense.objects.all().order_by('date')
     data = {}

     for exp in expenses:
         y = exp.date.strftime("%Y")
         if (data.has_key(y)):
             data[y].append(exp)
         else:
             data[y] = [exp]

     return render_to_response(request, "index.html", {"data": data})


 #html
 {% for year, expenses in data.items %}
   <h1> {{ year }} </h1>
   <ul>
     {% for expense in expenses %}
         <li><b>{{ expense.date|date:"M" }}:</b> {{ expense.amount }}</li>
     {% endfor %}
   </ul>
 {% endfor %}

你可以显然适合这种情况。这个想法非常简单 - 解析数据并在通过SQL获取数据后使用python进行排列。

答案 1 :(得分:0)

我终于能够得到预期的结果,但我真的不喜欢它。我仍然想知道是否有办法以类似于我所要求的方式解决这个问题。

基本上,我创建了另一个字典(amounts),用于查找expense中的年份,并根据它继续根据年份添加expense.amount。最后,amounts将类似于:{2013: Decimal('16.58'), 2014: Decimal('104.66')}

我的解决方案:

views.py

from django.template.defaulttags import register
...         
@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

def index(request):
    years = Expense.objects.dates('date','year')
    expenses = Expense.objects.all().values()
    amounts = {}

    for expense in expenses:
        year = expense['date'].year
        if year in amounts:
            amounts[year] = amounts[year] + expense['amount']
        else:
            amounts[year] = expense['amount']

    return render(request, 'index.html', {'years': years, 'amounts': amounts})

template

<tbody> 
  {% for year in years %}
    <tr>
      <td width="50%">
        <a href="{{year.year}}">
          {{ year.year }}
        </a>
      </td>
      <td width="50%" align="right">{% if year.year in amounts %} {{ amounts|get_item:year.year }} {% endif %}</td>
    </tr>
  {% endfor %}
</tbody>

有什么好主意吗? ;)