浏览代码

Fixed #30801 -- Improved guidance for making good use of signals.

Joseph Victor Zammit 2 年之前
父节点
当前提交
71e9694856
共有 2 个文件被更改,包括 35 次插入23 次删除
  1. 14 0
      docs/ref/signals.txt
  2. 21 23
      docs/topics/signals.txt

+ 14 - 0
docs/ref/signals.txt

@@ -22,6 +22,14 @@ Model signals
 The :mod:`django.db.models.signals` module defines a set of signals sent by the
 model system.
 
+.. warning::
+
+    Signals can make your code harder to maintain. Consider implementing a
+    helper method on a :ref:`custom manager <custom-managers>`, to
+    both update your models and perform additional logic, or else
+    :ref:`overriding model methods <overriding-model-methods>` before using
+    model signals.
+
 .. warning::
 
     Many of these signals are sent by various model methods like
@@ -546,6 +554,12 @@ Request/response signals
 
 Signals sent by the core framework when processing a request.
 
+.. warning::
+
+    Signals can make your code harder to maintain. Consider :doc:`using a
+    middleware </topics/http/middleware>` before using request/response
+    signals.
+
 ``request_started``
 -------------------
 

+ 21 - 23
docs/topics/signals.txt

@@ -11,38 +11,34 @@ allow certain *senders* to notify a set of *receivers* that some action has
 taken place. They're especially useful when many pieces of code may be
 interested in the same events.
 
-Django provides a :doc:`set of built-in signals </ref/signals>` that let user
-code get notified by Django itself of certain actions. These include some useful
-notifications:
+For example, a third-party app can register to be notified of settings
+changes::
 
-* :data:`django.db.models.signals.pre_save` &
-  :data:`django.db.models.signals.post_save`
+    from django.apps import AppConfig
+    from django.core.signals import setting_changed
 
-  Sent before or after a model's :meth:`~django.db.models.Model.save` method
-  is called.
-
-* :data:`django.db.models.signals.pre_delete` &
-  :data:`django.db.models.signals.post_delete`
-
-  Sent before or after a model's :meth:`~django.db.models.Model.delete`
-  method or queryset's :meth:`~django.db.models.query.QuerySet.delete`
-  method is called.
+    def my_callback(sender, **kwargs):
+        print("Setting changed!")
 
-* :data:`django.db.models.signals.m2m_changed`
+    class MyAppConfig(AppConfig):
+        ...
 
-  Sent when a :class:`~django.db.models.ManyToManyField` on a model is changed.
+        def ready(self):
+            setting_changed.connect(my_callback)
 
-* :data:`django.core.signals.request_started` &
-  :data:`django.core.signals.request_finished`
+Django's :doc:`built-in signals </ref/signals>` let user code get notified of
+certain actions.
 
-  Sent when Django starts or finishes an HTTP request.
+You can also define and send your own custom signals. See
+:ref:`defining-and-sending-signals` below.
 
-See the :doc:`built-in signal documentation </ref/signals>` for a complete list,
-and a complete explanation of each signal.
+.. warning::
 
-You can also `define and send your own custom signals`_; see below.
+    Signals give the appearance of loose coupling, but they can quickly lead to
+    code that is hard to understand, adjust and debug.
 
-.. _define and send your own custom signals: `defining and sending signals`_
+    Where possible you should opt for directly calling the handling code,
+    rather than dispatching via a signal.
 
 Listening to signals
 ====================
@@ -218,6 +214,8 @@ bound to the signal once for each unique ``dispatch_uid`` value::
 
     request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")
 
+.. _defining-and-sending-signals:
+
 Defining and sending signals
 ============================