Django 信号仅在 debug=True 时有效,DJANGO 3.2.4
Django signal only works when debug=True, DJANGO 3.2.4
我到处找,找不到任何相关参考,我的 Django 模型信号仅在 debug=True 时有效,但如果 debug=False 则无效,这在本地主机上都会发生和生产服务器。
我的设置如下所示:
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/"
如果设置为debug=False,则不会触发信号,也不会出现任何错误。
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()
当我更新到 psycopg
的新版本时,问题发生了,不知何故,在将我的 psycopg
更新到最新版本后,它现在工作正常。
这对我有用:
调用信号的 connect()
或 @receiver
时传递 weak=False。
Django Signals 提及警告:
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().
因此,您的接收函数可能正在被垃圾回收。
例如,尝试使用:@receiver(pre_delete, sender=ManualWithdrawals, weak=False)
只是为了对@kaustubh-trivei 的回答添加更多见解。
当处理程序以这种方式注册时:
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)
然后weak=False
是强制性的,否则它会被垃圾收集并立即取消注册。
由于实现细节,当 settings.DEBUG
为 True
时,Django 会创建一个额外的处理程序引用,以防止处理程序被垃圾收集和注销。
实现细节:当 settings.DEBUG
是 True
时,处理程序的参数由 django.utils.inspect
模块验证,该模块在内部使用 functools.lru_cache()
装饰器,这导致处理程序被存储作为 lru 缓存字典中的键。
我到处找,找不到任何相关参考,我的 Django 模型信号仅在 debug=True 时有效,但如果 debug=False 则无效,这在本地主机上都会发生和生产服务器。
我的设置如下所示:
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/"
如果设置为debug=False,则不会触发信号,也不会出现任何错误。
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()
当我更新到 psycopg
的新版本时,问题发生了,不知何故,在将我的 psycopg
更新到最新版本后,它现在工作正常。
这对我有用:
调用信号的 connect()
或 @receiver
时传递 weak=False。
Django Signals 提及警告:
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().
因此,您的接收函数可能正在被垃圾回收。
例如,尝试使用:@receiver(pre_delete, sender=ManualWithdrawals, weak=False)
只是为了对@kaustubh-trivei 的回答添加更多见解。
当处理程序以这种方式注册时:
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)
然后weak=False
是强制性的,否则它会被垃圾收集并立即取消注册。
由于实现细节,当 settings.DEBUG
为 True
时,Django 会创建一个额外的处理程序引用,以防止处理程序被垃圾收集和注销。
实现细节:当 settings.DEBUG
是 True
时,处理程序的参数由 django.utils.inspect
模块验证,该模块在内部使用 functools.lru_cache()
装饰器,这导致处理程序被存储作为 lru 缓存字典中的键。