Подсчитать количество последовательных строк с одинаковым значением для столбца в базе данных, используя django? - PullRequest
0 голосов
/ 10 января 2019

Мое приложение состоит из модуля уведомлений. Если уведомления последовательно поступают от одного и того же пользователя, я хотел бы показать «n уведомлений от Джона Доу».

например:

Строки базы данных имеют вид:

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

Вышеуказанные уведомления должны отображаться как:

2 notifications from john doe
2 notification from james
3 notofications from john doe

Как бы я посчитал эти последовательные строки с одинаковым значением в столбце, используя django orm?

Notification.objects.all().values('user', 'notif_count').group_consecutive_by('user').as(notif_count=Sum())

Нечто подобное. Пожалуйста, помогите.

1 Ответ

0 голосов
/ 11 января 2019

Пусть моя модель <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.

Готово!

...