Джанго сигналы и переопределить метод save
У меня возникли проблемы с обертыванием головы вокруг этого. Прямо сейчас у меня есть некоторые модели, которые выглядят примерно так:
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()
обзор имеет несколько "баллов", The overall_score является средним из баллов. Когда обзор или оценка сохраняется, мне нужно пересчитать среднее значение overall_score. Прямо сейчас я использую переопределенный метод сохранения. Будут ли какие-либо преимущества в использовании диспетчера сигналов Django?
6 ответов:
сигналы сохранения/удаления обычно благоприятны в ситуациях, когда вам нужно внести изменения, которые не полностью специфичны для рассматриваемой модели, или могут быть применены к моделям, которые имеют что-то общее, или могут быть настроены для использования в разных моделях.
одна общая задача в переопределенном
save
методы-это автоматизированная генерация слизней из некоторого текстового поля в модели. Это пример чего-то, что, если бы вам нужно было реализовать его для ряда моделей, было бы польза от использованияpre_save
сигнал, где обработчик сигнала может взять имя поля slug и имя поля для создания slug. Если у вас есть что - то подобное, любая расширенная функциональность, которую вы создаете, также будет применяться ко всем моделям-например, поиск слизняка, который вы собираетесь добавить для рассматриваемого типа модели, чтобы обеспечить уникальность.многоразовые приложения часто извлекают выгоду из использования сигналов-если функциональность, которую они предоставляют, может быть применительно к любой модели они обычно (если это не неизбежно) не хотят, чтобы пользователи должны были напрямую изменять свои модели, чтобы извлечь из этого выгоду.
С django-mptt, например, я использовал
pre_save
сигнал для управления набором полей, описывающих структуру дерева для модели, которая будет создана или обновлена иpre_delete
сигнал для удаления деталей древовидной структуры для удаляемого объекта и всего его поддерева объектов перед ним, и они удаленный. Благодаря использованию сигналов, пользователи не должны добавлять или изменятьsave
илиdelete
методы на своих моделях чтобы это управление было сделано для них, они просто должны позволить django-mptt знать, какие модели они хотят, чтобы он управлял.
ты спрашиваешь:
будут ли какие-либо преимущества в использовании диспетчера сигналов Django?
Я нашел это в документах django:
переопределенные методы модели не вызываются при массовых операциях
обратите внимание, что метод delete() для объекта не обязательно вызывается при массовом удалении объектов с помощью набора запросов или в результате каскадное удаление. Чтобы убедиться, что настроенная логика удаления выполняется, вы мочь используйте сигналы pre_delete и/или post_delete.
к сожалению, нет обходного пути при создании или обновлении объекты навалом, так как ни один из save (), pre_save и post_save не являются называемый.
Если вы будете использовать сигналы, вы сможете обновлять оценку обзора каждый раз, когда соответствующая модель оценки будет сохранена. Но если мне не нужна такая функциональность, я не вижу причин помещать это в сигнал, это довольно связанные с моделью вещи.
Это своего рода денормализация. Посмотри на это красивое решение. Определение поля композиции на месте.
небольшое дополнение от Django docs о массовом удалении (
.delete()
метод onQuerySet
объекты):имейте в виду, что это будет, когда это возможно, выполняться исключительно в SQL, и поэтому методы delete () отдельных экземпляров объектов будут не обязательно вызывать во время процесса. Если вы предоставили пользовательский метод delete () для класса модели и хотите убедиться, что это вызывается, вам нужно будет "вручную" удалить экземпляры этой модели (например, итерация по набору запросов и вызов метода delete() для каждого из них объект по отдельности) вместо использования метода массового удаления() a QuerySet.
https://docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects
и пакетное обновление (
.update()
метод onQuerySet
объекты):наконец, поймите, что update () выполняет обновление на уровне SQL и, таким образом, не вызывает никаких методов save() на ваших моделях и не делает этого излучать или pre_save сигнал post_save (которые являются следствием вызываю модель.спасать.))( Если вы хотите обновить кучу записей на модель, которая имеет пользовательский метод save (), перебирает их и вызывает save ()
https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update