【问题标题】:Django: What exactly are signals good for?Django:信号到底有什么用?
【发布时间】:2010-01-19 21:26:25
【问题描述】:

我很难理解信号是如何在我的应用程序中工作的(以及它们是如何工作的)。以下是我认为它们将适用的三个领域(以我目前的知识):

  1. 将 XML 发送到远程服务器进行报告(交易完成后)。
  2. 在用户上传后,重新调整图像大小并将缩略图上传到 S3。
  3. 在用户从其帐户中删除图像对象后,从 S3 中删除旧图像。

我是不是完全偏离了基地(我觉得我可能是)。 我是否将信号和多线程混淆了?如果是这样,他们会在应用程序中进行比较吗?它们只是为了脱钩吗?另外,确保尽早实例化它们并且不使用本地函数(因为它们会被垃圾收集)有什么关系?有人可以详细说明吗?我应该把它们都放在请求中间件中,这样我就不用担心了吗?

【问题讨论】:

  • 我不明白您对多线程的引用。有什么意义?
  • @Andrea Zilio 请参阅答案 1 上的 cmets

标签: django django-signals aop


【解决方案1】:

Django 信号是一种执行动作 A 以响应事件 E 的方式。

在虚幻世界中,您可以通过修改发生事件E 的代码并附加代码以执行操作A 来避免使用信号。

问题在于,这样做会失去可维护性、可读性和许多其他软件工程形容词:)

信号允许您独立地从事件E 发生的位置或方式执行相同的操作,并且以一种允许可维护性、可读性等的巧妙方式这样做......

是的,我认为信号对于启用解耦很有用的说法是真的。

(您还提到了多线程。如果您这样做是因为您认为信号很好,因为它们是并发执行的,而且执行速度如此之快……嗯……我不知道它们是否同时执行,但无论如何我真的不知道'不认为这是 django 信号有用的重点)

利用 Signals 的一个好方法的一个例子是,当您想在 django 中将其他信息存储给用户时,您必须使用 Userprofiles。 在这种情况下,documentation itself 告诉您,注册一个信号以响应任何新用户的创建可能很方便,只需向新创建的用户添加一个空的用户配置文件。

【讨论】:

  • Django 信号肯定是同步调度的。
  • @Ignacio 我的意图不是说信号是同时执行的,而是试图想象为什么在问题中提到了多线程......我不知道它们是如何处理的。现在我愿意。谢谢伊格纳西奥;)
  • 您是否认为我列表中的 3 个任务可以通过信号来执行?
  • 我提到多线程的原因不是为了并发优势,而是为了用户看到“谢谢”页面并且它已经完成加载但服务器中仍在进行的情况。这可能吗?
  • 任务 1,并非如此。只需将代码上传到交易代码之后即可。任务2,当然。但是你最好把它完全放在一个单独的过程中。任务 3,可能,尽管在任务中使用“删除”这个词如果没有正确完成可能会导致不雅代码。
【解决方案2】:

这是一个可能有帮助的例子。

假设您需要在保存模型实例时执行一些操作。但是,此操作与模型或模型实例本身没有直接关系。因此,将您的操作代码放在模型上的 save() 方法中几乎没有意义。这会导致不必要的代码耦合和混乱。相反,您可以在应用程序的其他地方(甚至在另一个应用程序)中创建一个信号处理程序,这样更有意义。

【讨论】:

    【解决方案3】:

    我会使用类似异步任务队列的东西执行任务 2 和 3(图像内容),例如 Celery

    这类似于多线程。

    【讨论】:

      【解决方案4】:

      信号不是异步的(不是以并发或并行方式运行)

      这就是为什么它们对您提到的事情如此有用:

      • 文件上传或文件后处理
      • 报告生成
      • 任何其他长期操作(对另一台服务器的请求,ET)

      最好Celery 可以以真正异步的方式进行长期操作的工作人员。

      但它们在一些有限的场景中仍然很有价值

      • 扩展第三方库的功能。如果您使用的应用程序包含您不控制代码的模型,则信号是比猴子补丁更强大的替代方案,用于在保存或删除时执行特定操作。
      • 删除信号适用于删除查询集方法。如果您希望对单个对象和查询集删除都执行相同的操作,则最好使用信号。
        注意:由于 SQL 的生成方式,这不会适用于更新查询集方法(带有保存信号)。另一个常见的混淆/错误来源。
      • 当您需要将相同的信号处理程序应用于多个模型时。如果您只有几个,我仍然倾向于覆盖保存/删除方法并调用共享函数。对于很多人来说,到处复制/粘贴 save 方法变得更容易出错,而且信号看起来是一个更好的选择。
      • 避免紧密的跨应用程序依赖。如果您需要跨越应用程序边界,特别是当应用程序可能在多个项目中使用时,信号可能更适合应用程序之间的松散耦合。不过要小心这个。使用它是因为您需要,而不是因为您认为您将来可能需要它。

      这些案例和一些例子你可以找到in this topic

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-13
        • 2020-06-26
        • 1970-01-01
        • 2021-12-17
        • 2010-10-08
        • 1970-01-01
        • 2021-10-30
        相关资源
        最近更新 更多