我需要为我的项目的每个应用程序有单独的信号.但在其中一个应用程序中保存模型后,所有应用程序都会触发信号,所以我复制了信号中的信息.为Django项目的不同应用程序设置信号的正确方式是什么?

我的app1的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 }')

apps.py of my app1:

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

下面是我的项目settings.py中的记录器部分

'loggers': {
        'django': {
            'handlers': ['console',],
            'propagate': False,
            'level': 'INFO',
        },
        'app1.signals': {
            'handlers': ['console', 'file'],
            'level': 'INFO',
        },
        'app2.signals': {
            'handlers': ['console', 'file'],
            'level': 'INFO',
        },
     }

推荐答案

这完全有道理:应用程序在功能上并没有那么孤立,它只是使得在一个单独的应用程序中导出模型和逻辑,然后将它们插入到另一个项目中变得容易,从而使代码增加了reusable个.

但如果你制作了一个监听post_save个信号的信号,那么在保存any个APP的模型时就会触发.信号处理程序不会限制监听自己应用程序的模型.这也会过多地限制信号:例如,它将使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',如果没有,我们就忽略它.

Django相关问答推荐

如何根据递归ManyToManyField值创建Django查询集?

如何使用Django';S生成的字段来统计相关对象?

在Django中使用Generil.ListView类时,分页不起作用

Django迁移嵌套模型时出错,不带迁移基本模型

如何从列中捕获数据并将其添加到下拉菜单中,以便表单填充另一个表

Django中的DateTimeField到DateField

执行官/start.sh:没有这样的文件或目录

从一个组中获取所有用户 - Django

变量为无时默认模板标签输出的Django设置?

Django REST Framework - 将额外参数传递给操作

如何在 django 中生成 url

Django App 配置不当 - 应用程序模块有多个文件系统位置

Django populate() 不可重入

模型 Django 中的 ID 字段

如何在 Django 和 django-jsonfield 中将 JSONField 的默认值设置为空列表?

清理提交的表单数据中的 HTML

如何在 django 元素中开始做 TDD?

模型表格Save保存,Get获取保存的对象

django/文件上传权限

Django中'related_name'和'related_query_name'属性之间的区别?