Django signal only works when debug=True, DJANGO 3.2.4
Asked Answered
T

4

7

I've been looking everywhere and I coulnd't find any reference about this, my Django model signal only works when the debug=True, but it doesn't work if debug=False, this occur both on localhost and production server.

My settings looks like this:

settings.py

from pathlib import Path
import os
import environ

env = environ.Env()

environ.Env.read_env()

BASE_DIR = Path(__file__).resolve().parent.parent

#production
STATIC_ROOT = 'https://d1u356tnw52tcs.cloudfront.net/'


SECRET_KEY = env("SECRET_KEY_PROD")

DEBUG = True

ALLOWED_HOSTS = ['*']

CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
)


# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'django.contrib.postgres',
    'sellrapp',
    'stock_management',
    'corsheaders',
    'drf_yasg',
    'optimized_image',
    'csvexport',
    'kronos',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'corsheaders.middleware.CorsMiddleware'
]

ROOT_URLCONF = '****.urls'


WSGI_APPLICATION = '****.wsgi.application'


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': env("NAME_PROD"),
        'USER': env("USER_PROD"),
        'PASSWORD': env("PASSWORD_PROD"),
        'HOST': env("HOST_PROD"),
        'PORT': env("PORT_PROD"),
    }
}

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Singapore'

USE_I18N = True

USE_L10N = True

USE_TZ = True


WEB_BASE_URL = 'https://****.com/'
BASE_URL_LIVE_CAMPAIGN = WEB_BASE_URL + "product/"

if set to debug=False, the signal wouldn't triggered, and there's no any error trown.

signals.py

from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save, pre_delete
from .models import ManualWithdrawals


@receiver(pre_delete, sender=ManualWithdrawals)
def manual_wd(sender, instance, **kwargs):
    order = ManualWithdrawals.objects.get(id=instance.id)
    consumer_order = order.order_id_list.all()
    sample_order = order.sample_order_id_list.all()
    total = str(instance.total_withdrawals).replace(".", "")
    total = int(total)
    if instance.order_id_list:
        for order in consumer_order:
            if instance.type == "reseller" and order.reseller_commission_status != "paid":
                order.reseller_commission_status = "ready for collection"
                order.save()
            if instance.type == "merchant" and order.merchant_commission_status != "paid":
                order.merchant_commission_status = "ready for collection"
                order.save()
        # updating sample order if any
    if instance.sample_order_id_list:
        for order in sample_order:
            if instance.type == "merchant" and order.merchant_commission_status != "paid":
                order.merchant_commission_status = "ready for collection"
                order.save()
Thermistor answered 31/8, 2021 at 17:43 Comment(3)
Can you try any other signals like pre_save just to see if it is working so that we can confirm it is a project-level issue and not specific to this signal?Sharitasharity
pre_save and all method is also not working... is it possible because I'm using django-environ.readthedocs.io/en/latest/# ? @SharitasharityThermistor
Facing the same issue. Has anyone found any solution?Weatherley
T
0

Turn out that the problem happening when I'm updating to a new version of psycopg, somehow after updating my psycopg to the latest version now it's working just fine.

Thermistor answered 18/9, 2021 at 16:51 Comment(2)
What version are you using?Weatherley
Sorry but updating to latest version of psycopg does not work for meWeatherley
W
11

This worked for me:

Pass weak=False when you call the signal’s connect() or @receiver.


Django Signals mention warning that:

Note also that Django stores signal handlers as weak references by default, so if your handler is a local function, it may be garbage collected. To prevent this, pass weak=False when you call the signal’s connect().

Thus, it is possible that your receiver function is getting garbage-collected.

For example, try using: @receiver(pre_delete, sender=ManualWithdrawals, weak=False)

Weatherley answered 19/10, 2021 at 11:40 Comment(0)
S
5

Just to add more insights to @kaustubh-trivei answer.

When handler is registered this way:

from django.db.models.signals import post_save

def create_and_register_handler(model):
    def handler(sender, instance=None, created=False, **kwargs):
        ...

    post_save.connect(handler, sender=model)

then weak=False is manadatory, otherwise it gets garbage collected and unregistered immediately.

Due to implementation detail, when settings.DEBUG is True, Django creates one extra reference to the handler, which prevents the handler from being garbage collected and unregistered.

Implementation detail: when settings.DEBUG is True, handler's arguments get validated by django.utils.inspect module, which uses functools.lru_cache() decorator internally, which leads to the handler being stored as a key in lru cache dict.

Septal answered 10/1, 2022 at 10:57 Comment(0)
W
2

We got the same error, it's because of using the same function name for 2 signals.

@reciever(....)
def set_something(...):
    pass

@reciever(...)
def set_something(...): # This function name is the same as above
    pass
Waterproof answered 12/8, 2023 at 16:40 Comment(0)
T
0

Turn out that the problem happening when I'm updating to a new version of psycopg, somehow after updating my psycopg to the latest version now it's working just fine.

Thermistor answered 18/9, 2021 at 16:51 Comment(2)
What version are you using?Weatherley
Sorry but updating to latest version of psycopg does not work for meWeatherley

© 2022 - 2024 — McMap. All rights reserved.