7

I am having trouble to figure out whether my signal handler is called during fixture loading or not. Most of my signal handlers receive an extra keyword raw when django load fixtures. However, this extra keyword only get passed through when handling 'pre/post' signals, it doesn't get pass through if the signal I am listening to is m2m_changed!

Is there any reliable way to tell whether I am in a "fixture loading mode" or not with m2m_changed

Meitham
  • 9,178
  • 5
  • 34
  • 45

1 Answers1

0

Well, if anyone found this just like me, one horrible, horrible way to solve this is the following:

https://code.djangoproject.com/ticket/8399#comment:7

In this old ticket of the django Project a way to determine whether a signal was triggered form a loaddata or not is requested.

After this, the raw keyword was the proposed solution, which does not appear in the m2m_changed signal. Before that there was the following proposed workaround, which still works:

try:
    from functools import wraps
except ImportError:
    from django.utils.functional import wraps

import inspect


def disable_for_loaddata(signal_handler):
    @wraps(signal_handler)
    def wrapper(*args, **kwargs):
        for fr in inspect.stack():
            if inspect.getmodulename(fr[1]) == 'loaddata':
                return
        signal_handler(*args, **kwargs)
    return wrapper

You can than use this decorater to disable any signal on loaddata, like this:

from django.db.models.signals import m2m_changed
from django.dispatch import receiver


@receiver(m2m_changed, sender=models.Foo.bar.through)
@disable_for_loaddata
def some_signal(sender, instance: models.Foo, action: str, **kwargs):
    # signal code