我需要为项目的每个应用程序提供单独的信号。但是,在其中一个应用程序中保存模型后,所有应用程序都会触发信号,因此我的信号中出现了重复的消息。为 Django 项目的不同应用程序设置信号的正确方法是什么?
我的应用程序1的signals.py:
# -*- coding: utf-8 -*-
import logging
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import *
@receiver(post_save)
def log_app1_updated_added_event(sender, **kwargs):
'''Writes information about newly added or updated objects of app1 into log file'''
logger = logging.getLogger(__name__)
app1_object = kwargs['instance']
if kwargs['created']:
logger.info(f'added {app1_object }')
else:
logger.info(f'updated {app1_object }')
我的应用程序2的signals.py:
# -*- coding: utf-8 -*-
import logging
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import *
@receiver(post_save)
def log_app2_updated_added_event(sender, **kwargs):
'''Writes information about newly added or updated objects of app2 into log file'''
logger = logging.getLogger(__name__)
app2_object = kwargs['instance']
if kwargs['created']:
logger.info(f'added {app2_object }')
else:
logger.info(f'updated {app2_object }')
我的 app1 的 apps.py:
from django.apps import AppConfig
class App1Config(AppConfig):
name = 'App1'
def ready(self):
from app1 import signals
我的app2的apps.py:
from django.apps import AppConfig
class App1Config(AppConfig):
name = 'App2'
def ready(self):
from app2 import signals
这是我的项目设置中的记录器部分。py
'loggers': {
'django': {
'handlers': ['console',],
'propagate': False,
'level': 'INFO',
},
'app1.signals': {
'handlers': ['console', 'file'],
'level': 'INFO',
},
'app2.signals': {
'handlers': ['console', 'file'],
'level': 'INFO',
},
}
这很有道理:应用程序在功能上并没有那么隔离,它只是让您可以轻松地在单独的应用程序中导出模型和逻辑,然后将它们插入到另一个项目中,从而使代码更加可重用。
但是,如果您创建一个监听
post_save
信号的信号,则在保存 any 应用程序的模型时会触发该信号。信号处理程序不限制监听其自己的应用程序的模型。这也会过多地限制信号:例如,它会导致无法监听 User
模型的变化,因为这是在 django.contrib.auth
应用程序中定义的。
但是我们可以对其进行过滤,仅让信号仅处理其自己应用程序的模型对象:
@receiver(post_save)
def log_app1_updated_added_event(sender, instance, **kwargs):
'Writes information about newly added or updated objects of app1 into log file'
if sender._meta.app_label == 'app1':
logger = logging.getLogger(__name__)
app1_object = instance
if kwargs['created']:
logger.info(f'added {app1_object }')
else:
logger.info(f'updated {app1_object }')
因此,我们检查模型是否有
app_label
即 'app1'
,如果没有,我们就忽略它。