我需要跟踪用户最近一次在帖子中被提及的时间,并在每次基于其帖子时间创建新帖子时更新此字段。
我当前的代码如下:

from django.db.models.signals import post_save
from django.dispatch import receiver
from messageboard.models import Post

@receiver(post_save, sender=Post)
def user_last_mentioned_updater(sender, instance, **kwargs):
    for users in instance.mentions:
        user.last_mentioned = max(user.last_mentioned, instance.timestamp)
        user.save()

但是,如果同时处理两个post,则可能会在前面post的时间戳处留下last_mentioned字段。
不幸的是,F不支持max操作,当我尝试时,得到一个TypeError: unorderable types: datetime.datetime() > F()
user.last_mentioned = max(F('last_mentioned'), instance.timestamp)

我怎样才能避免这种比赛状态?
如果重要的话,目前我正在使用Postgresql进行ORM,尽管这可能会有所改变。

最佳答案

这里有一个版本,应该是自由的比赛条件和更有效的:

@receiver(post_save, sender=Post)
def user_last_mentioned_updater(sender, instance, **kwargs)
    User.objects.filter(
        id__in=[u.id for u in instance.mentions],
        last_mentioned__lt=instance.timestamp,
    ).update(last_mentioned=instance.timestamp)

也就是说,我们选择需要更新时间戳的用户,并在单个SQL语句中更新它们。

10-06 15:49
查看更多