Как запустить действие после сохранения модели и связанных полей m2m (групп)? - PullRequest
3 голосов
/ 13 мая 2019

Как сделать что-то после сохранения пользовательской модели 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() метод - но я застрял ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...