Является ли сигнал post_save в Django атомным? - PullRequest
0 голосов
/ 06 апреля 2019

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

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 при каждом сохранении объекта обзора. Это атомное? Я определенно хочу, чтобы все это было атомарным, поскольку ситуация, когда рецензия сохраняется, но общая оценка предмета не обновляется, является рецептом для ошибок.

1 Ответ

1 голос
/ 07 апреля 2019

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

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

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

class Review(models.Model):
    ...

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