不同应用程序的 Django 信号

问题描述 投票:0回答:1

我需要为项目的每个应用程序提供单独的信号。但是,在其中一个应用程序中保存模型后,所有应用程序都会触发信号,因此我的信号中出现了重复的消息。为 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',
        },
     }
django django-signals
1个回答
0
投票

这很有道理:应用程序在功能上并没有那么隔离,它只是让您可以轻松地在单独的应用程序中导出模型和逻辑,然后将它们插入到另一个项目中,从而使代码更加可重用

但是,如果您创建一个监听

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'
,如果没有,我们就忽略它。

© www.soinside.com 2019 - 2024. All rights reserved.