使用Django计算数据库中列的具有相同值的连续行?

时间:2019-01-10 07:25:46

标签: python django django-models django-views

我的应用程序包含一个通知模块。如果通知是连续从同一用户到达的,我想显示“ n个来自john doe的通知”。

例如:

数据库行为:

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 :(得分:1)

让我的模型Notification模型为:


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

基本上,我正在尝试通过user联接连续的行

以上通知将显示为:

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']),
]

因此,我们首先按Notificationsdate_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中对所有内容进行了排序。

完成!