Пусть моя модель <b>Notification</b>
модель будет:
Class Notification(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
related_name='notifications',
on_delete=models.CASCADE)
notif = models.CharField(max_length=255)
date_created = models.DateTimeField(auto_now_add=True)
Строки базы данных имеют вид:
id | user | notif |
------------------------------------
1 john doe liked your pic
2 john doe commented on your pic
3 james liked your pic
4 james commented on your pic
5 john doe pinged you
6 john doe showed interest
7 john doe is busy
Обычно я пытаюсь объединить последовательные строки на <b>user</b>
Указанные выше уведомления должны быть показаны как:
2 notifications from john doe
2 notification from james
3 notofications from john doe
вместо
5 notifications from john doe
2 notification from james
или
1 notifications from john doe
1 notifications from john doe
1 notification from james
1 notification from james
1 notofications from john doe
1 notofications from john doe
1 notofications from john doe
Чтобы достичь этого, мы ищем словарь:
{
"john doe": ["notif1", "notif2"],
"james": ["notif1", "notif2"],
"john doe": ["notif1", "notif2", "notif3"] #duplicate key.
}
Но это невозможно, поскольку дубликаты ключей не допускаются. Поэтому вместо этого я собираюсь использовать массив кортежей.
[
('john doe', ['notif1', 'notif2']),
('james', ['notif1', 'notif2']),
('john doe', ['notif1', 'notif2', 'notif3']),
]
Итак, сначала мы сортируем <b>Notifications</b>
по date_created
. Затем мы используем itertools.groupby
для создания групп на пользователя.
from itertools import groupby
from operator import attrgetter
qs = Notification.objects.select_related('user').order_by('date_created')
notifs= [(u, list(nf)) for (u, nf) in groupby(qs, attrgetter('user'))]
У вас все отсортировано по необходимости в notifs
.
Готово!