我这里有一个超级简单的django模型:
class Notification(models.Model):
message = models.TextField()
user = models.ForeignKey(User)
timestamp = models.DateTimeField(default=datetime.datetime.now)
Run Code Online (Sandbox Code Playgroud)
使用ajax,我每分钟检查一下新消息.我只会随时向用户显示最近的五个通知.我想避免的是以下场景.
用户登录并且没有通知.当用户的窗口启动时,他会收到10条新消息.因为我只向他展示五个,没什么大不了的.当用户开始删除他的通知时会发生此问题.如果他删除了显示的五个,那么五个旧的将在下一个ajax调用或刷新时显示.
我希望我的模型的save方法除了保存新的对象外,还会删除5个最新的对象.不幸的是,你不能用[5:]来做这件事.救命?
编辑
我试过这个没有按预期工作(在模型的保存方法中):
notes = Notification.objects.filter(user=self.user)[:4]
Notification.objects.exclude(pk__in=notes).delete()
Run Code Online (Sandbox Code Playgroud)
我找不到奇怪行为的模式,但经过一段时间的测试后,它只会在创建新模式时删除最新的模式.我不知道为什么会这样.在模型的Meta类中处理排序(按时间戳降序).感谢您的帮助,但我的方式似乎是唯一一致的.
Jor*_*tao 35
这有点旧,但我相信你可以做到以下几点:
notes = Notification.objects.filter(user=self.user)[:4]
Notification.objects.exclude(pk__in=list(notes)).delete() # list() forces a database hit.
Run Code Online (Sandbox Code Playgroud)
它需要两次点击,但避免使用带有事务中间件的for循环.
使用的原因list(notes)是Django在没有它的情况下创建了一个查询,并且在Mysql 5.1中,这会引发错误
(1235, "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'")
Run Code Online (Sandbox Code Playgroud)
通过使用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()
Run Code Online (Sandbox Code Playgroud)
ist*_*ble 11
使用内部查询来获取要保留的项目集,然后对其进行过滤.
objects_to_keep = Notification.objects.filter(user=user).order_by('-created_at')[:5]
Notification.objects.exclude(pk__in=objects_to_keep).delete()
Run Code Online (Sandbox Code Playgroud)
在使用之前请仔细检查.我发现更简单的内部查询并不总是按预期运行.我遇到的奇怪行为仅限于只是order_by和slice的查询集.由于你必须过滤用户,你应该没事.
这就是我最终做到这一点的方式.
notes = Notification.objects.filter(user=self.user)
for note in notes[4:]:
note.delete()
Run Code Online (Sandbox Code Playgroud)
因为我在save方法中这样做,循环必须运行多次的唯一方法就是用户一次收到多个通知.我并不担心这种情况发生(虽然它可能会发生但不足以导致问题).
| 归档时间: |
|
| 查看次数: |
17488 次 |
| 最近记录: |