| 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] |