Django中的Signal代码详解

下面我会详细讲解“Django中的Signal代码详解”的完整攻略,包括两条示例说明。

什么是Signals

Signal是Django框架中一种提供了统一解耦机制的工具。Signal机制可以在软件设计中完成消息的发布和订阅功能。简单来说,Signal是一种django中内部|跨应用程序的非阻塞通信方式。

优点是:
1. 内部处理自由方便,不受调用方影响;
2. 降低代码的耦合度,提高代码的可读性;
3. 方便人性化的日志配置;

Signal的使用

安装django

若已安装,可省略此步骤。

pip install django

创建一个django项目并生成一个应用程序

django-admin startproject project
cd project
python manage.py startapp testapp # testapp为应用程序名

使用Signal完成应用程序之间的通信

Django中的Signal模块主要由以下几部分组成:

  • 可在你的应用程序中本地声明的信号。
  • 当接收到信号时将被调用的监听器

发送Signals

Signals在Django中使用django.dispatch.Signal来创建。下面我们首先创建一个signal:

我们对于信号有两种方式来定义一个信号,一种就是使用Signal类,另一种就是使用signal装饰器。

我们先看看使用Signal类的方式:

# testapp.signals module

from django.dispatch import Signal

test_signal = Signal(providing_args=['arg1', 'arg2'])

监听Signals

下一步我们需要监听这个signal,并且在收到这个信号时做出反应。在Django中监听者可以是一个函数,当信号被发出时,此函数会被调用。

如下所示,我们定义一个函数,当信号被发出时就会调用此函数:

# testapp.signals listener

def handler(sender, **kwargs):
    print(sender)
    print(kwargs)


test_signal.connect(handler)

handler函数定义了两个参数:sender**kwargs。其中sender实际指信号所发送的当前模版类,**kwargs为提供给监听器的参数。

函数connect可以将信号和监听函数绑定在一起。当事件发送时,我们先来看看会输出什么。

Test Signal

现在看完了简答的信号和监听器,接下来让我们看看它们在Django项目中是如何协作的。

我们在某个地方发送signal:

# testapp.function sender
from .signals import test_signal

test_signal.send(sender=self.__class__, arg1='arg1', arg2='arg2')

Send方法:它用于将信号发送给一个或多个接收器,作为一个“写入入口”,使用Signal.connect()方法将多个接收器绑定到同一个信号上,该方法将逐一触发该信号。

最后,让我们来创建一个Django的示例程序,演示信号和监听器是如何协同工作的。

一个Django的示例程序

创建一个名为Signaltute的Django项目和一个名为Testapp的应用程序:

django-admin startproject signaltute
cd signaltute
python manage.py startapp testapp

现在我们来为我们的应用创建一些新的文件:

# signals.py
from django.dispatch import Signal

test_signal = Signal() # 创建信号
# listeners.py
from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.dispatch import receiver

from testapp.signals import test_signal


User = get_user_model()
# 发送者  要获得当前发送信息的model
# **kwargs 从信号发送者获得的实际值

@receiver(test_signal)
def test_signal_handler(sender, **kwargs):
    print("aaa")


@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    print("test")

# models.py
# -*- coding: utf-8 -*-
from django.db import models


class BaseModel(models.Model):
    class Meta:
        abstract = True


class Test(BaseModel):
    name = models.CharField(max_length=32)

    def __str__(self):
        return self.name

运行python manage.py makemigrations && python manage.py migrate, Django便可创建相应的表。

最后,在应用的views.py中添加以下代码:

import random

from django.contrib.auth import get_user_model
from django.http import HttpResponse
from django.shortcuts import render
from django.views.generic import TemplateView

from testapp.listeners import test_signal_handler
from testapp.models import Test
from testapp.signals import test_signal

User = get_user_model()


class HomePageView(TemplateView):
    template_name = 'home.html'


def test_signal_view(request):
    test_signal.connect(test_signal_handler) # 绑定信号和监听器
    test_instance = Test(name=f'test_instance_{random.randint(1, 100)}')
    test_instance.save()
    test_signal.send(sender=request.user)
    return HttpResponse('OK')

请注意,我们在test_signal_view中连接了test_signal并指定test_signal_handler为它的接收者。

运行Django开发服务器并通过URL http://127.0.0.1:8000/test_signal/ 调用test_signal_view视图。

test_signal_handler是最终的监听器,我们期望代码输出”aaa”

示例二

signals.py:

from django.dispatch import Signal
# 创建一个信号hr_read
hr_read = Signal(providing_args=["request", "workflow", "todo", "data"])

使用Signal类是最基本、最灵活的方式。这允许我们在运行时添加或删除接收器,并允许我们在不使用“post_ **”信号的情况下发出自己的信号。

以下是单个监听器的示例:

from django.dispatch import receiver
from .signals import hr_read


@receiver(hr_read)
def read_the_mail(sender, **kwargs):
    print(sender)
    print(kwargs)

在接收到信号hr_read时,将打印sender和kwargs。

Q&A

  • 区别Signal和其他消息传递机制(例如在Python中的类events.Event)
    Signals是帮助我们将我们的代码解耦的工具,因为它们实现了事件驱动的交互模型。Signals允许我们将事件从方法或逻辑中分离出来,最大程度地减少代码的聚合组件。与其他事件通知模型不同的是,Signals不是一种阻塞消息传递模型,而是一种灵活、松散的事件传递模型,这是一种十分基于异步通信的解决方案。

  • 如何在应用中使用多个监听器?
    Signal可以被多个接收器绑定,我们把一个信号绑定到两个接收器,它会将信号传递给两个接收器。但是,我们需要保证这两个接收器不相互干扰。

  • admin功能,自动化邮件如何使用Signal来实现?

    django.contrib.auth.signals.user_logged_in
    在登录后每次活动中触发,允许其他应用程序扩展来封锁或界定特定时期的管理操作。邮箱提醒可以帮助管理员监控此优先级外部事件。

以上就是Django中的Signal的详细攻略,希望对你有所帮助!

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django中的Signal代码详解 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月16日

相关文章

  • Django之ORM性能优化建议

    前言   DjangoORM数据层提供各种途径优化数据的访问。   如果事先理解Django的优化技巧,开发过程中稍稍留意,后期会省不少的工作量。 正题 一,利用标准数据库优化技术 传统数据库优化技术博大精深,不同的数据库有不同的优化技巧,但重心还是有规则的。在这里算是题外话,挑两点通用的说说:  索引,给关键的字段添加索引,性能能更上一层楼,如给表的关联字…

    Django 2023年4月13日
    00
  • django2.0 报错 does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.

      raise ImproperlyConfigured(msg.format(name=self.urlconf_name)) django.core.exceptions.ImproperlyConfigured: The included URLconf ‘<module ‘users.urls’ from ‘D:\\mygitfile\\mei…

    Django 2023年4月9日
    00
  • Django通用视图APIView和视图集ViewSet的介绍和使用(Django编程-1)

    1.APIView DRF框架的视图的基类是 APIViewAPIView的基本使用和View类似 Django默认的View请求对象是 HttpRequest,REST framework 的请求对象是 Request。Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果。HttpRequest.GET ————> Request.…

    Django 2023年4月11日
    00
  • Django 外键的使用方法详解

    Django 外键的使用方法详解 在 Django 中,外键是一种非常重要的关系型字段,它可以用于表之间的关联,方便数据的操作和查询。本文将详细讲解 Django 外键的使用方法,包括什么是外键、外键的类型、外键的创建和使用,以及外键的常见问题解决。 什么是外键 外键是一种关系型字段,它用来在两个表之间建立关联。通过外键字段,我们可以将一张表中的数据和另一张…

    Django 2023年5月16日
    00
  • Nginx+ uWSGI +django进行部署

    一:uWSGI的安装 sudo pip install uwsgi 如果安装报错: conda install -c conda-forge uwsgi conda install -c conda-forge libiconv   测试 test.py: uwsgi –http :8020 –chdir /mnt/d/hegh/projects/080…

    Django 2023年4月10日
    00
  • Django路由Path方法详解(详细步骤)

    Django中的路由系统是通过URLconf(URL配置)来实现的。URLconf将URL模式映射到视图函数或类上。在Django中,我们可以使用两种方式来定义URLconf,一种是使用基于函数的视图,另一种是使用基于类的视图。 在URLconf中,我们需要使用路由函数来匹配URL模式,Django提供了两种路由函数:path()和re_path()。在本文…

    Django 2023年3月12日
    00
  • 关于django 数据库迁移(migrate)应该知道的一些事

    那我来详细讲解关于Django数据库迁移(Migrate)需要知道的一些事情及相关示例。 概述 Django的ORM(Object-Relational Mapping,对象关系映射)是非常强大的,它允许我们在Django项目中使用Python对象操作数据库。当我们创建一个Django应用时,我们需要定义模型(Model),Django会自动将它们映射为关系…

    Django 2023年5月16日
    00
  • 《Django By Example》第一章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example原作者:Antonio Melé 2016年12月10日发布(没有进行校对,有很多错别字以及模糊不清的语句,请大家见谅) 2017年2月7日精校完成(断断续续的终于完成了第一章精校,感觉比直接翻译还要累,继续加油) 2017年2月10日再次…

    Django 2023年4月11日
    00
合作推广
合作推广
分享本页
返回顶部