Сигналы Django против основного метода сохранения

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

 def Review(models.Model)
    ...fields...
    overall_score = models.FloatField(blank=True)

def Score(models.Model)
    review = models.ForeignKey(Review)
    question = models.TextField()
    grade = models.IntegerField()

В обзоре есть несколько "баллов", total_score - это среднее значение баллов. Когда обзор или оценка сохранены, мне нужно пересчитать среднее значение total_score. Сейчас я использую метод переопределенного сохранения. Будут ли какие-либо выгоды от использования диспетчера сигналов Django?

Ответ 1

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

Одной из общих задач в переопределенных методах save является автоматическая генерация пулов из некоторого текстового поля в модели. Это пример того, что, если вам нужно было реализовать его для ряда моделей, выиграло бы от использования сигнала pre_save, где обработчик сигнала мог бы взять имя поля slug и имя поля для генерации пробка из. Как только у вас будет что-то подобное, любые расширенные функциональные возможности, которые вы вводите на место, также применимы ко всем моделям - например, глядя на слизь, которую вы собираетесь добавить для типа модели, о которой идет речь, для обеспечения уникальности.

Многоразовые приложения часто получают выгоду от использования сигналов - если функциональность, которую они предоставляют, может применяться к любой модели, они обычно (если это не неизбежно) не хотят, чтобы пользователям приходилось напрямую модифицировать свои модели, чтобы извлечь выгоду из нее.

С django-mptt, например, я использовал сигнал pre_save для управления набором полей, которые описывают древовидную структуру для модель, которая должна быть создана или обновлена, и сигнал pre_delete для удаления данных древовидной структуры для удаляемого объекта и всего его поддерева объектов перед ним и они будут удалены. Из-за использования сигналов пользователям не нужно добавлять или изменять методы save или delete на своих моделях, чтобы сделать это управление для них, они просто должны позволить django-mptt знать, какие модели они хотят, чтобы управления.

Ответ 2

Вы спросили:

Были ли какие-либо преимущества использования диспетчера сигналов Django?

Я нашел это в django docs:

Переопределенные методы модели не вызывают массовые операции

Обратите внимание, что метод delete() для объекта не обязательно называется при удалении объектов в массе с помощью QuerySet или в результате каскадное удаление. Чтобы обеспечить выполнение индивидуальной логики удаления, вы могут использовать сигналы pre_delete и/или post_delete.

К сожалению, не существует обходного пути при создании или обновлении объекты навалом, поскольку ни одно из save(), pre_save и post_save не является называется.

От: Переопределение предопределенных методов модели

Ответ 3

Если вы будете использовать сигналы, вы сможете обновить оценку Review каждый раз, когда соответствующая модель баллов будет сохранена. Но если мне не нужна такая функциональность, я не вижу никакой причины помещать это в сигнал, этот довольно связанный с моделью материал.

Ответ 4

Это своего рода денормализация. Посмотрите на это отличное решение. Определение поля на месте.

Ответ 5

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