瀏覽代碼

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
 The :mod:`django.db.models.signals` module defines a set of signals sent by the
 model system.
 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::
 .. warning::
 
 
     Many of these signals are sent by various model methods like
     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.
 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``
 ``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
 taken place. They're especially useful when many pieces of code may be
 interested in the same events.
 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
 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")
     request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")
 
 
+.. _defining-and-sending-signals:
+
 Defining and sending signals
 Defining and sending signals
 ============================
 ============================