2017-05-25 11 views
2

ユーザーがポストに記載された最新の時刻を記録し、ポストタイムに基づいて新しいポストが作成されるたびにこのフィールドを更新する必要があります。モデルフィールドを最新のタイムスタンプに更新する際の競合状態を回避する方法

私の現在のコードは次のようになります。

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

2つのポストが同時に処理されている場合は、これは潜在的に以前の記事のタイムスタンプでlast_mentionedフィールドを残すことができます。

user.last_mentioned = max(F('last_mentioned'), instance.timestamp) 

どのように私は、この競合状態を避けることができます。

残念ながら、Fは、私はそれをしようとしたとき、私はTypeError: unorderable types: datetime.datetime() > F()を取得し、max操作をサポートしていませんか?

現時点では、私はORMにPostgreSQLを使用していますが、これは変更される可能性があります。

@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文では、更新を必要とし、それらを更新しています言及したユーザーを選択し、次のとおりです。

答えて

2

ここで競合状態の自由で、より効率的であるべきバージョンです。

+0

ありがとう、これは完全に機能しました。 – AJMansfield

関連する問題