| | 53 | {{{ dispatcher.connect(create_contenttypes, signal=signals.post_syncdb) }}} |
| | 54 | |
| | 55 | The first argument, `create_contenttypes`, is the name of the function to execute when the signal is sent out. The second argument, `signal`, is the signal to listen for. There is another optional argument, `sender`, which is not used in this example; `sender` can be used to narrow down exactly what will be listened for; when you specify `sender`, your function will only be executed when the object which sent the signal is the same as the object you specify as the `sender` argument. |
| | 56 | |
| | 57 | An example of this can be found in Django's authentication application: `django.contrib.auth.management` defines a function called `create_superuser`, and uses the dispatcher to connect to the `post_syncdb` signal -- but ''only'' when `post_syncdb` is being sent as a result of installing the auth application. To do this, the auth app's `management.py` file imports its own models: |
| | 58 | |
| | 59 | {{{ from django.contrib.auth import models as auth_app }}} |
| | 60 | |
| | 61 | And then uses the `sender` argument to `dispatcher.connect`: |
| | 62 | |
| | 63 | {{{ dispatcher.connect(create_superuser, sender=auth_app, signal=signals.post_syncdb) }}} |
| | 64 | |
| | 65 | Here's a breakdown of exactly why that works: |
| | 66 | |
| | 67 | 1. Whenever `manage.py syncdb` finishes installing the models for a particular application, it sends the `post_syncdb` signal. You'll remember that `dispatcher.send` takes an optional argument, `sender`, which is the object that's "sending" the signal. In this case, `manage.py syncdb` sets `sender` to be the `models` module of the app it just installed. |
| | 68 | 2. `django.contrib.auth.management` import the auth app's models as `auth_app`, which means that, within that file, the variable `auth_app` ''is'' the module `django.contrib.auth.models`. |
| | 69 | 3. So when `manage.py syncdb` send the `post_syncdb` signal with `django.contrib.auth.models` as the `sender` argument, the dispatcher notices that this is the same as the `sender` specified in the `dispatcher.connect` call in `django.contrib.auth.management`, and so the `create_superuser` function is executed. |
| | 70 | |
| | 71 | In case you've ever wondered, that's how Django knows to prompt you to create a superuser whenever you install the auth app for the first time. The auth app also sets up another function -- `create_permissions` -- which doesn't specify `sender` in its call to `dispatcher.connect`, so it runs any time `post_syncdb` is sent. That's how the auth app creates the add, change and delete `Permission` objects for each application you install. |
| | 72 | |
| | 73 | == List of signals built in to Django == |
| | 74 | |
| | 75 | Django defines several sets of signals which are used internally, and which you can listen for in order to run your own custom code at specific moments. |
| | 76 | |
| | 77 | `django.db.models.signals` defines the following signals: |
| | 78 | |
| | 79 | '''class_prepared''' |
| | 80 | |
| | 81 | This is sent whenever a model class has been "prepared"; in other words, once most of the metaprogramming which makes models work has been completed. Django uses this signal internally to know when to generate and add the automatic `AddManipulator` and `ChangeManipulator` to a model class (see the DevModelCreation page for details). |
| | 82 | |
| | 83 | Arguments that are sent with this signal: |
| | 84 | |
| | 85 | * `sender` -- the model class which was just prepared. |
| | 86 | |
| | 87 | '''pre_init''' |
| | 88 | |
| | 89 | Whenever you create a new instance of a Django model (for example, in [http://www.djangoproject.com/documentation/tutorial1/ the first part of the Django tutorial] when you do `p = Poll(question="What's up?", pub_date=datetime.now())`) , this signal is sent at the beginning of the execution of the model's `__init__` method. |
| | 90 | |
| | 91 | Arguments sent with this signal: |
| | 92 | |
| | 93 | * `sender` -- the model class you're creating an instance of. |
| | 94 | * `args` -- a list of positional arguments passed to the model's `__init__` method. |
| | 95 | * `kwargs` -- a dictionary of keyword arguments passed to the model's `__init__` method. For example, in the tutorial when you do `p = Poll(question="What's up?", pub_date=datetime.now())`, the `kwargs` argument to the `pre_init` signal would be the dictionary `{'question': "What's up?", 'pub_date': datetime.now()}`. |
| | 96 | |
| | 97 | '''post_init''' |
| | 98 | |
| | 99 | Like `pre_init`, but this one is sent when the model's `__init__` method is done executing. |
| | 100 | |
| | 101 | Arguments sent with this signal: |
| | 102 | |
| | 103 | * `sender` -- the model class you've just created an instance of. |
| | 104 | * `instance` -- the instance of the model you just created. For example, in the tutorial when you do `p = Poll(question="What's up?", pub_date=datetime.now())`, the `instance` argument to the `post_init` signal would be the `Poll` object you just created. |
| | 105 | |
| | 106 | ''pre_save''' |
| | 107 | |
| | 108 | This is sent at the beginning of a model's `save` method. |
| | 109 | |
| | 110 | Arguments sent with this signal: |
| | 111 | |
| | 112 | * `sender` -- the model class of the object being saved. |
| | 113 | * `instance` -- the actual object being saved. |
| | 114 | |
| | 115 | '''post_save''' |
| | 116 | |
| | 117 | This is sent at the end of a model's `save` method. |
| | 118 | |
| | 119 | Arguments sent with this signal: |
| | 120 | |
| | 121 | * `sender` -- the model class of the object which was just saved. |
| | 122 | * `instance` -- the actual object which was just saved. |
| | 123 | |
| | 124 | '''pre_delete''' |
| | 125 | |
| | 126 | This is sent at the beginning of a model's `delete` method. |
| | 127 | |
| | 128 | Arguments sent with this signal: |
| | 129 | |
| | 130 | * `sender` -- the model class of the object which is about to be deleted. |
| | 131 | * `instance` -- the actual object which is about to be deleted. |
| | 132 | |
| | 133 | '''post_delete''' |
| | 134 | |
| | 135 | This is sent at the end of a model's `delete` method. |
| | 136 | |
| | 137 | Arguments sent with this signal: |
| | 138 | |
| | 139 | * `sender` -- the model class of the object which was just deleted. |
| | 140 | * `instance` -- the actual object which was just deleted (the object will no longer be in the database, but will stick around in memory for a little while after that). |
| | 141 | |
| | 142 | '''post_syncdb'' |
| | 143 | |
| | 144 | Sent by `manage.py syncdb` after it installs an application. |
| | 145 | |
| | 146 | Arguments sent with this signal: |
| | 147 | |
| | 148 | * `sender` -- the `models` module of the application which was just installed. |
| | 149 | * `app` -- same as `sender`. |
| | 150 | * `created_models` -- a list of the model classes which were just installed. |
| | 151 | * `verbosity` -- indicates how much information `manage.py` is printing on screen. There are three possible values: 0 means no information, 1 means some information and 2 means all possible information. Functions which listen for this signal should adjust what they output to the screen based on the value of this argument. |
| | 152 | * `interactive` -- whether `manage.py` is running in "interactive" mode; this is a boolean and so is either `True` or `False`. If `interactive` is `True`, it's safe to prompt the user to input things on the command line (for example, the auth app only prompts to create a superuser when `interactive` is `True`); if `interactive` is `False`, functions which listen for this signal should not try to prompt for anything. |
| | 153 | |
| | 154 | `django.core.signals` defines the following signals: |
| | 155 | |
| | 156 | '''request_started''' |
| | 157 | |
| | 158 | This signal is sent whenever Django begins processing an incoming HTTP request. |
| | 159 | |
| | 160 | This signal doesn't provide any arguments. |
| | 161 | |
| | 162 | '''request_finished''' |
| | 163 | |
| | 164 | This signal is sent whenever Django finishes processing an incoming HTTP request. |
| | 165 | |
| | 166 | This signal doesn't provide any arguments. |
| | 167 | |
| | 168 | '''got_request_exception''' |
| | 169 | |
| | 170 | This signal is sent whenever Django encounters an exception while processing an incoming HTTP request. |
| | 171 | |
| | 172 | This signal doesn't provide any arguments. |
| | 173 | |
| | 174 | `django.test.signals` defines the following signals: |
| | 175 | |
| | 176 | '''template_rendered''' |
| | 177 | |
| | 178 | This signal is sent by Django's testing framework whenever the test system renders a template; it's used by the test system to verify that the template rendered as expected. |
| | 179 | |
| | 180 | Arguments sent with this signal: |
| | 181 | |
| | 182 | * `sender` -- the `Template` object which was rendered. |
| | 183 | * `template` -- same as `sender`. |
| | 184 | * `context` -- the `Context` with which the template was rendered. |
| | 185 | |
| | 186 | == Other documentation == |
| | 187 | |
| | 188 | * [http://feh.holsman.net/articles/2006/06/13/django-signals Django signals] -- blog entry by Ian Holsman which discusses signals in general. |
| | 189 | * [http://www.bright-green.com/blog/2006_07_12/initialising_application_data_.html Initializing application data in Django] -- blog entry by Alan Green which discusses use of the `post_syncdb` signal to provide initial application data. |
| | 190 | * [http://www.b-list.org/weblog/2006/09/10/django-tips-laying-out-application Django tips: laying out an application] -- blog entry by James Bennett which mentions the use of the `post_syncdb` signal to execute custom functions when an application is installed. |
| | 191 | |
| | 192 | == Applications not bundled with Django which use signals == |
| | 193 | |
| | 194 | * [http://zyons.com/ Zyons] |