Django删除除最后五个查询之外的所有查询

2024-04-25 10:15:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我这里有一个超级简单的django模型:

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

使用ajax,我每分钟都检查新消息。我在任何时候都只向用户显示最近的五个通知。我试图避免的是下面的场景。

用户登录后没有通知。当用户的窗口打开时,他会收到10条新消息。因为我只给他看了五张,没什么大不了的。当用户开始删除他的通知时,就会出现问题。如果他删除了显示的5个,那么下一次ajax调用或刷新时将显示5个旧的。

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

编辑

我尝试了这个没有按预期工作的方法(在模型的save方法中):

    notes = Notification.objects.filter(user=self.user)[:4]
    Notification.objects.exclude(pk__in=notes).delete()

我在奇怪的行为中找不到模式,但是经过一段时间的测试,它只会在创建新的模式时删除最近的模式。我不知道为什么会这样。在模型的元类中处理排序(按时间戳降序)。谢谢你的帮助,但我的方式似乎是唯一一个一贯有效的。


Tags: 对象django方法用户模型消息datetimeobjects
3条回答

这有点老了,但我相信你可以做到以下几点:

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()

使用内部查询获取要保留的项集,然后对其进行筛选。

objects_to_keep = Notification.objects.filter(user=user).order_by('-created_at')[:5]
Notification.objects.exclude(pk__in=objects_to_keep).delete()

使用前仔细检查一下。我发现更简单的内部查询并不总是按预期的方式运行。我所经历的奇怪行为仅限于querysets,它只是一个命令和一个片段。因为你必须根据用户进行筛选,所以你应该很好。

我就是这样做的。

    notes = Notification.objects.filter(user=self.user)
    for note in notes[4:]:
        note.delete()

因为我是在save方法中这样做的,所以循环必须多次运行的唯一方法是用户一次收到多个通知。我不担心会发生这种事(虽然可能会发生,但不太可能引起问题)。

相关问题 更多 >

    热门问题