Является ли сигнал post_save в Django атомарным?

#django #django-signals

#django #django-signals

Вопрос:

Я действительно не могу найти ничего надежного в документах. Допустим, я делаю что-то вроде этого:

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

class Item(models.Model):
    total_score = models.IntegerField()

    def set_score(self):
         ...

class Review(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    score = models.IntegerField()

@receiver(post_save, sender=Review)
def my_handler(sender, **kwargs):
    sender.item.set_score()
  

То, что я пытаюсь сделать, это вызвать set_score() для объекта item всякий раз, когда сохраняется объект review. Это атомарно? Я определенно хочу, чтобы все это было атомарным, поскольку ситуация, когда обзор сохраняется, но общий балл элемента не обновляется, является рецептом ошибок.

Ответ №1:

Нет, в сигналах нет ничего особенного в отношении транзакций базы данных (единственный вид атомарности, обрабатываемый Django). Вам решать, чтобы соответствующие команды всегда были частью одной и той же транзакции базы данных.

Одним из подходов было бы просто полагаться на вызывающий код, чтобы сделать это с помощью ATOMIC_REQUESTS , используя транзакции в ваших представлениях и т.д.

Или, поскольку post_save сигналы отправляются как часть Model.save() , вы могли бы просто переопределить Review.save() и заставить его использовать транзакцию.

 class Review(models.Model):
    ...

    @transaction.atomic()
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)