我在这里有一个 super 简单的Django模型:

class Notification(models.Model):
    message = models.TextField()
    user = models.ForeignKey(User)
    timestamp = models.DateTimeField(default=datetime.datetime.now)

我使用ajax每分钟检查一次新消息。我只会随时向用户显示五个最新通知。我要避免的是以下情况。

用户登录并且没有通知。当用户的窗口打开时,他会收到10条新消息。因为我只给他看五个,所以没什么大不了的。当用户开始删除他的通知时,就会发生此问题。如果他删除显示的五个,则五个较旧的将显示在下一个ajax调用或刷新中。

我想让我的模型的save方法在保存一个新对象时删除除5个最新对象之外的所有对象。不幸的是,您不能使用[5:]来执行此操作。帮助?

编辑

我尝试了这个没有按预期工作的方法(在模型的save方法中):
    notes = Notification.objects.filter(user=self.user)[:4]
    Notification.objects.exclude(pk__in=notes).delete()

我找不到奇怪行为的模式,但是经过一段时间的测试,它只会在创建新模式时删除最新模式。我不知道为什么会这样。排序在模型的Meta类中进行(按时间戳降序排列)。感谢您的帮助,但我的方法似乎是唯一始终如一的方法。

最佳答案

这有点旧,但是我相信您可以执行以下操作:

notes = Notification.objects.filter(user=self.user)[:4]
Notification.objects.exclude(pk__in=list(notes)).delete()  # list() forces a database hit.

它花费了两笔费用,但避免将for循环与事务中间件一起使用。

使用list(notes)的原因是Django在没有它的情况下创建了一个查询,并且在Mysql 5.1中会引发错误
(1235, "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'")

通过使用list(notes),我们避免了notes的查询。
可以进一步优化以:
notes = Notification.objects.filter(user=self.user)[:4].values_list("id", flat=True)  # only retrieve ids.
Notification.objects.exclude(pk__in=list(notes)).delete()

关于python - Django删除查询集的最后五个,除最后五个,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1851197/

10-16 01:30