Как сделать что-то после сохранения пользовательской модели Django, включая изменения в полях m2m, такие как django.contrib.auth.models.Group
?
Ситуация
У меня есть пользовательская модель Django, и я хочу вызвать некоторыеДействия после пользовательского экземпляра - с соответствующими изменениями, такими как членство в группах m2m - успешно сохраняются в базе данных.В данном случае используется Wagtail CMS, где я создаю ProfilePage
s для каждого пользовательского экземпляра.В зависимости от членства в группах экземпляра пользователя мне нужно что-то делать.
Проблема
В методе пользовательской модели save()
я не могу ссылаться на измененное членство в группе,м2м сохраняются после сохранения пользовательского экземпляра.Даже если моя пользовательская функция запускается после вызова super().save()
, новые членства в группах пока недоступны.Но мне нужно получить членство в новых группах, чтобы что-то делать в зависимости от новых групп для этого пользователя.
То, что я пробовал
[✘] Пользовательская модель save()
# file: users/models.py
class CustomUser(AbstractUser):
super().save(*args, **kwargs)
do_something()
[✘] Сигнал post_save
Поскольку вышеприведенный простой метод save () не сработал, я попробовал сигнал post_save
пользовательской модели:
# file users/signals.py
@receiver(post_save, sender=get_user_model())
def handle_profilepage(sender, instance, created, **kwargs):
action = 'created' if created else 'updated'
do_something()
... но даже здесь я всегда получаю "старые" значения от членства в группе.
[✔] Сигнал: m2m_changed
Я узнал, что есть сигнал m2m_changed
, с помощью которого я могу отслеживать изменения в таблице Users.groups(.through)
.
Моя следующая реализация сделала то, что мне нужно:
@receiver(m2m_changed, sender=User.groups.through)
def user_groups_changed_handler(sender, instance, **kwargs):
USER_GROUPS = instance.groups.values_list('name', flat=True)
if set(USER_GROUPS) & set(settings.PROFILE_GROUPS):
do_something_because_some_groups_match()
else:
do_something_else()
Мой список желаний
Я бы с радостью держался подальше от сигналов, если бы была возможность решить эту проблему в моделяхsave()
метод - но я застрял ...