@newvasyuki

Почему не сохраняется m2m?

Есть две модели и сигнал

class Hobby(models.Model):
    name = models.CharField(max_length=255)

class User(models.Model):
    main_hobby = models.ForeignKey(Hobby, null=True, blank=True, on_delete=models.SET_NULL)
    hobbies = models.ManyToManyField(Hobby, blank=True)

@receiver(pre_save, sender=User):
def update_hobbies(sender,  instance, **kwargs):
     if instance.main_hobby:
          instance.hobbies.add(instance.main_hobby)


В итоге поле hobbies не обновляется. Пробовал и post_save - картина та же. Сам сигнал отрабатывает, но ничего не сохраняется. ЧЯДНТ?
  • Вопрос задан
  • 44 просмотра
Пригласить эксперта
Ответы на вопрос 1
Assargin
@Assargin
Перед ответом смотрю наличие ✔ в ваших вопросах
Итак, вы сохраняете из админки, а это значит, что ваш сигнал (post_save надо, pre_save тут точно мимо) отрабатывает сразу после того, как будет сохранён объект User. Пока всё ок.

Но именно с админкой есть нюанс: после того, как сохранится основная модель и выполнятся соответствующие этому действию сигналы, начнётся сохранение m2m связей, которые 100% у вас есть на странице админки, и перезапишут те данные, которые вы миллисекундами ранее сохранили с помощью сигнала.

У меня была когда-то похожая проблема, и если мне не изменяет память, я создавал свой сигнал, который вызывал из переопределённого метода класса админки модели после сохранения вообще всего, а в обработчике своего кастомного сигнала уже спокойно работал с m2m-связями без этих проблем.

Также, можно поиграться с имеющимся в Django сигналом m2m_changed, но это будет костыль, потому что этот сигнал будет вызван 2N раз, где N - число добавлений/удалений из m2m.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы