我的问题与this post几乎完全相同,只是我使用的是Python和Django而不是PHP。
任务是:
id date
1 2009-01-01 10:15:23
2 2009-01-01 13:21:29
3 2009-01-02 01:03:13
4 2009-01-03 12:20:19
5 2009-01-03 13:01:06
输出:
2009-01-01
1
2
2009-01-02
3
2009-01-03
4
5
我可以通过循环排序日期并在我的python视图文件中将HTML输出到字符串中来手动破解某些东西,但我想知道:使用Django模板或漂亮的Python功能有更好的方法吗?
答案 0 :(得分:31)
您可以使用重新组合和日期模板标签解决此问题。
{% regroup object_list by start_date|date:"Y-m-d" as objects_by_day %}
{% for d in objects_by_day %}
### DO SOMETHING HERE
{% endfor %}
答案 1 :(得分:15)
itertools.groupby
是亲爱的,亲爱的朋友:
import itertools
dates = [
(1,'2009-01-01 10:15:23'),
(2,'2009-01-01 13:21:29'),
(3,'2009-01-02 01:03:13'),
(4,'2009-01-03 12:20:19'),
(5,'2009-01-03 13:01:06'),
]
for key,group in itertools.groupby(dates, key=lambda x: x[1][:11]):
print key
for element in group:
print ' ', element
以上代码打印以下内容:
2009-01-01
(1, '2009-01-01 10:15:23')
(2, '2009-01-01 13:21:29')
2009-01-02
(3, '2009-01-02 01:03:13')
2009-01-03
(4, '2009-01-03 12:20:19')
(5, '2009-01-03 13:01:06')
答案 2 :(得分:9)
对较大数据集itertools.group_by
执行报告时可能会太慢。在那些情况下,我让postgres处理分组:
truncate_date = connection.ops.date_trunc_sql('day','timestamp')
qs = qs.extra({'date':truncate_date})
return qs.values('date').annotate(Sum('amount')).order_by('date')
答案 3 :(得分:8)
如果OP可以在模板代码中使用python,这些都是合理的答案。 (在那个帐户上,我赞成使用itertools.groupby()解决方案。)但是你不能在模板代码中使用python。在最好的情况下,您将编写执行此操作的模板标签。并且已经有一个模板标签可以做到这一点。
要在模板中的Django中进行分组,请使用重新组合:
{% regroup people by gender as gender_list %}
<ul>
{% for gender in gender_list %}
<li>{{ gender.grouper }}
<ul>
{% for item in gender.list %}
<li>{{ item.first_name }} {{ item.last_name }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
示例从Django regroup documentation解除。重新组合至少在django 0.96,1.0和1.1中可用。
如果你让我知道传递给模板的内容,我可以破解一个使用你的数据的例子。
此外,还有一个blog post,其中DjangoGrrl可以正好解决这个问题。
答案 4 :(得分:2)
如果您使用数据库的日期格式化功能去除时间(在选择中),这会更容易。然后,您可以按格式化列进行分组(使用列别名)。
之后,您可以使用具有一点逻辑的循环将结果转换为您想要的结果。我还没有使用过django的模板系统,但这是Python中的逻辑:
>>> rows = [(1,'2009-01-01'), (2,'2009-01-01'), (3, '2009-02-02'), \
(4, '2009-02-02'), (5, '2009-02-02')]
>>> topdate = None
>>> for r in rows:
... if topdate <> r[1]:
... topdate = r[1]
... print r[1]
... print r[0]
...
2009-01-01
1
2
2009-02-02
3
4
5
应该有一种直接的方式将其转换为django模板代码。