Обработка метода сохранения модели с использованием атомарной транзакции в Django - PullRequest
1 голос
/ 06 апреля 2019

Вопрос, честно говоря, довольно понятен.У меня есть 2 модели, которые связаны между собой.Это выглядит так:

from django.db import IntegrityError, transaction

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

    def save(self, *args, **kwargs):
        try:
            with transaction.atomic():
                super(Review, self).save(*args, **kwargs)
                self.item.set_score()
        except IntegrityError:
            handle_exception()

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

Примечание. Я знаю, что есть более эффективные способы оценки балла за предмет на основе его отзывов.Это не суть вопроса.Это выдуманный сценарий, чтобы объяснить, что я хочу сделать.Так что, пожалуйста, никаких ответов об этом.

1 Ответ

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

Да, вы можете сделать это, как уже упоминалось, но лучше использовать бизнес-логика / логика транзакций вне метода save (). Это обеспечит вам лучшую целостность, а также абстракцию.

Запись этой логики внутри функции сохранения - это сокращение ( довольно просто ).

другой способ сделать это

utils.py

def update_score(*args, **kwargs):
    with transaction.atomic():
        review = Review(*args, **kwargs)
        review.item.set_score()
        review.save()

Если это не помогло бы вам, чем писать этот блок транзакции в методе save () или просто выбрать свой код в другом методе и обернуть его с исключением, но обработать этот блок try-catch с правильным исключением, поскольку он вызывает побочные эффекты / Багги код. В остальном все будет хорошо и будет работать.

Просто помните, что не обрабатывайте исключения внутри атомарного блока транзакции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...