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视图函数

    Django是一个基于Python的Web框架,具有灵活性和高效性。在Django中,视图(views)是处理Web请求并返回Web响应的核心组件之一。本文将详细讲解Django视图函数的基本概念以及如何编写和使用Django视图函数。 概念 视图函数负责处理Web请求并生成Web响应。在Django中,一个视图函数通常会接收一个或多个HTTP请求,并返回一…

    Django 2023年3月11日
    00
  • Django unittest测试框架特性详解

    Django是一个非常流行的Python web框架,其中包括一个集成的unittest测试框架。在本攻略中,我们将详细介绍如何使用Django unittest测试框架。 步骤1:创建测试模块 首先,我们需要创建一个测试模块来存储我们的单元测试。我们可以在项目的根目录中创建一个名为“tests.py”的文件,或者创建一个名为“tests”的目录,并在其中创…

    Django 2023年3月13日
    00
  • Django将项目移动到新环境的操作步骤

    Django项目移动到新环境的操作步骤: 导出原项目数据 在原项目的根目录下执行以下命令,导出原项目的数据: python manage.py dumpdata > data.json 备份原项目数据库 使用数据库管理工具(如phpMyAdmin等)备份原项目数据库。 在新环境中安装依赖 在新环境中安装Django所需的依赖,可以使用pip命令进行安装…

    Django 2023年5月16日
    00
  • 代码详解django中数据库设置

    下面将为你详细讲解“代码详解django中数据库设置”的完整攻略。 1.概述 Django 中的数据库设置可以通过在 settings.py 文件中设置 DATABASES 变量来实现。DATABASES 变量是一个字典,它包含了三个必须的键像这样: DATABASES = { ‘default’: { ‘ENGINE’: ‘django.db.backen…

    Django 2023年5月16日
    00
  • Django values()和value_list()的使用

    对于Django中的查询是非常重要的一个部分,我们来详细讲解一下Django的values()和values_list()方法的使用。 Django values()方法 values()方法是在Django ORM框架中使用的一个方法,它可以用于从数据库中返回指定字段的值。可以理解为用于指定查询操作的选择器。values()方法返回的结果是一个QueryS…

    Django 2023年5月16日
    00
  • Django框架—-render函数和redirect函数的区别

    render函数和redirect函数的区别: render:只会返回页面内容,但是未发送第二次请求 redirect:发挥了第二次请求,url更新 具体实例说明 render: redirect:

    Django 2023年4月12日
    00
  • 浅谈Django的缓存机制

    当用户访问Django站点时,站点会执行非常多的代码来渲染页面。 如果每次都重新执行这些代码,将会影响站点的性能和用户的体验。为了优化性能,Django提供了一种缓存机制,可以将结果缓存到内存或文件系统中,从而减少重复执行代码的时间。 缓存机制的几种实现方式 Django的缓存机制支持多种后端,可以选择使用内存或文件系统等多种方式储存缓存数据。Django官…

    Django 2023年5月16日
    00
  • django用户注册、登录、注销和用户扩展的示例

    让我来详细讲解一下关于“Django用户注册、登录、注销和用户扩展的示例”的攻略。 概述 在Django中,用户认证是开箱即用的,也就是说你可以方便地创建用户账户、实现登录认证等操作。本攻略将介绍基本的Django用户认证流程,以及如何通过扩展用户模型的方法增加字段来完成用户注册和登录的过程。 本文涉及到的环境以及版本信息如下: Python 3.7.9 D…

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