2017-07-27 9 views
0

Djangoモデルでインスタンスを同期的に更新するには?私は2つのモデル持っ

class TranslatedLesson(models.Model): 
created_at = models.DateTimeField(auto_now_add=True) 
updated_at = models.DateTimeField(auto_now=True) 
amount_steps = models.IntegerField(default=0) 

class TranslationStep(models.Model): 
lesson = models.ForeignKey(TranslatedLesson, on_delete=models.CASCADE, related_name="steps") 
created_at = models.DateTimeField(auto_now_add=True) 
updated_at = models.DateTimeField(auto_now=True) 


@receiver(post_save, sender=TranslationStep, 
dispatch_uid="update_lesson_date") 
def update_lesson_date(sender, instance, **kwargs): 
    lesson = instance.lesson 
    lesson.update_date = instance.updated_at 
    lesson.save() 

私はTranslationStepモデルを更新するたびに、私はTranslatedLessonがありupdated_at時間を、更新したいです。しかし、上のコードは、レッスンがもう少し保存されるので、私には異なる結果をもたらします。 auto_now=Trueを削除して.saveメソッドをオーバーライドしても、目的の結果が得られません。

>>> step.updated_at 
    datetime.datetime(2017, 7, 27, 7, 59, 24, 912420, tzinfo=<UTC>) 
>>> lesson.updated_at 
    datetime.datetime(2017, 7, 27, 7, 59, 24, 919461, tzinfo=<UTC>) 

更新を同期的に実行するにはどうすればよいですか?

+0

あなたは、単に 'TranslatiedLessonにauto_now'属性を削除でき、そして' save'メソッドをオーバーライドしていない - ちょうどその操作を行うために所定の位置に 'receiver'機能を残します作業? – an0o0nym

+0

@ an0o0nym問題は私が他の場所で 'updated_at'を自動的に更新することです。 –

+0

あなたはなぜこのことが重要であるか説明する必要があります。もちろん、時代は少し違っていて、本当に同期して起こることはありません。時間が全く同じであれば、何をしているのですか?それを行うためのより良い方法であることは絶対に確かです。 –

答えて

1

TranslatedLesson.save()を自動的にupdate_dateにしたいので、ここではTranslatedLesson.save()を使用できません。解決策はusing QuerySet.update() insteadによってTranslatedLesson.save()への呼び出しをバイパスすることです:

receiver(post_save, sender=TranslationStep, dispatch_uid="update_lesson_date") 
def update_lesson_date(sender, instance, **kwargs): 
    qs = TranslatedLesson.objects.filter(id=instance.lesson_id) 
    qs.update(updated_at=instance.updated_at) 
+0

私はそれがどのように動作するのか、djangoのドキュメントでは競合状態さえも防ぐことができると言われています。 –

+0

ドキュメントで言及されているように、モデルレイヤーではなくダイレクトSQL更新クエリを発行することで動作します。これは競合状態を防ぐ方法についても説明しています。 –

関連する問題