Использование 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
и сказать «игнорировать получатель операции, если операция была отредактирована как часть формы задания»? Есть ли альтернативные решения?