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

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

使用Ajax,我每分钟都会判断新消息.我在任何时候都只向用户显示最近的五个通知.我想要避免的是下面的场景.

用户登录后没有任何通知.当用户的窗口打开时,他会收到10条新消息.因为我只给他看了5个,没什么大不了的.当用户开始删除他的通知时,问题就会发生.如果他删除了显示的五个,则较早的五个将在下一次Ajax调用或刷新时显示.

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

EDIT

我try 了这个方法,但没有按预期效果(在模型的保存方法中):

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

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

推荐答案

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

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创建了一个没有它的查询,在MySQL5.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()

Django相关问答推荐

错误``Forbidden (403) CSRF 验证失败.请求中止.``` 当try 登录管理员时

try 在 django 中发送验证邮箱,出现错误

测试 - 两个类共享相同的登录代码,但它只能在一个类中工作

Django基于查询集动态筛选字段名称

Django中的InvalidOperation错误[]

Django如何在没有ctrl点击的情况下允许多选

无法创建超级用户,因为 Django 中的一列(外键)不能为空

Django获取具有值的相关对象的计数并将其添加到注释中

Django 模板:翻译带有 HTML 的文本块的最佳实践

我的 django 模板布尔变量在 javascript 中没有按预期工作

django 管理员登录突然要求 csrf 令牌

Django REST Framework ModelSerializer get_or_create 功能

Django BigInteger自动增量字段作为主键?

Python/Django:从 values_list() 创建一个更简单的列表

如何使用 django 发送 POST 请求?

使用 lambda 作为属性的默认值时,Django 1.7.1 Makemigrations 失败

在 Django 中使用 AuthenticationForm

django 我们可以在预取相关模型上 Select 一个字段吗?

ModelForm 上的 Django 和字段集

Python Django 的多线程