Мой вопрос почти такой же, как этот пост, за исключением того, что я использую 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
Я могу вручную взломать что-то вместе, перейдя по отсортированным датам и выведя HTML в строку в моем файле представления python, но мне интересно: есть ли лучший способ использовать шаблон Django или отличную функцию Python?
Ответ 1
Вы можете решить эту проблему с помощью шаблонов tempatetags для групп и групп.
{% regroup object_list by start_date|date:"Y-m-d" as objects_by_day %}
{% for d in objects_by_day %}
### DO SOMETHING HERE
{% endfor %}
Ответ 2
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')
Ответ 3
Когда отчеты больших наборов данных 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')
Ответ 4
Это все разумные ответы, если OP может использовать python в коде шаблона. (И в этом случае я бы предпочел решение itertools.groupby().) Но вы не можете использовать python в коде шаблона. В лучшем случае вы должны написать templatetag, который выполнил эту операцию. И уже есть templatetag, который делает это.
Чтобы выполнить группировку в 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. перегруппировка доступна в django 0.96, 1.0, и 1.1, по крайней мере.
Если вы дали мне представление о том, что передается шаблону, я могу взломать пример, который использует ваши данные.
Кроме того, есть сообщение в блоге, в котором DjangoGrrl работает именно по этому вопросу.
Ответ 5
Это было бы проще, если бы вы использовали функции форматирования даты в базе данных, чтобы отключить время (в выборе). Затем вы можете группировать форматированный столбец (используя псевдоним столбца).
После этого вы можете использовать цикл с небольшой логикой, чтобы перенести результаты на то, что вы хотите. Я еще не использовал систему шаблонов 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.