Джанго: Использование сигналов с встроенными моделями - PullRequest
1 голос
/ 04 апреля 2019

Использование Django 2.2

У меня есть две модели, Job и Operation, где Operation имеет отношение внешнего ключа к Job (т. Е. Задание может иметь 0 или более операций).

Я хочу, чтобы люди вместе вводили информацию о заданиях и операциях через интерфейс администратора Django, используя inlines . (Это означает, что на сайте администратора на странице создания / редактирования задания пользователь может добавить одну или несколько операций «inline», не покидая страницы.)

Job имеет несколько полей, вычисленных из связанных с ним операций. Вместо того, чтобы просто делать их вычисленными @property свойствами, я хочу, чтобы они были обычными полями базы данных, которые обновляются при изменении операций с помощью сигналов. Это выглядит примерно так:

class Job(models.Model):
    name = models.CharFields(...)

    def compute_fields(self):
        qs = self.operations.filter(...)  # get data from operations
        self.name = ...  # set properties using that data
        self.save()
    ...


class Operation(models.Model):
    job = models.ForeignKey(Job, related_name="operations", on_delete=models.CASCADE)
    ...


@receiver(post_save, sender=Operation)
def update_job_on_operation_save(sender, instance, **kwargs):
    """Update job fields when an operation is saved"""
    instance.job.compute_fields()

Вот проблема: Если кто-то редактирует форму Job в Django Admin, и он добавляет несколько операций в строке перед нажатием кнопки сохранения, то функция-получатель вызывается несколько раз одновременно. Меня немного беспокоит состояние гонки, а также неэффективность каждого сигнала, заставляющая Job пересчитывать некоторые свойства и сохранять в базе данных.

Возможно, было бы лучше присоединить получатель к Job, поэтому функция вызывается только один раз, но если кто-то отредактирует Operation за пределами формы Job, что также должно вызвать перерасчет .

Можно ли настроить одинаковые post_save приемники для Job и Operation и сказать «игнорировать получатель операции, если операция была отредактирована как часть формы задания»? Есть ли альтернативные решения?

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