|
| 1 | +# Signals |
| 2 | +Django has long supported "signals", a feature that can be really useful. It allows you to get notified in a callback when a certain event occurs. One of the most common use cases is connecting to model signals. These signals get triggered when a model gets saved, or deleted. |
| 3 | + |
| 4 | +Django's built-in signals have one major flaw: |
| 5 | + |
| 6 | +* The `QuerySet.update(..)` method does **not** emit **any** signals. |
| 7 | + |
| 8 | +Because of this limitation, Django's signals cannot be reliably used to be signaled on model changes. `django-postges-extra` adds three new signals which are much more primitive, but work reliably across the board. |
| 9 | + |
| 10 | +The signals defined by this library are completely valid, standard Django signals. Therefore, their documentation also applies: [https://docs.djangoproject.com/en/1.10/topics/signals/](https://docs.djangoproject.com/en/1.10/topics/signals/). |
| 11 | + |
| 12 | +Each of the signals send upon model modification send one parameter containing the value of the primary key of the row that was affected. Therefore the signal's signature looks like this: |
| 13 | + |
| 14 | + def my_receiver(sender, pk: int): |
| 15 | + # pk is the primary key, a keyword argument |
| 16 | + |
| 17 | +## psqlextra.signals.create |
| 18 | +Send **after** a new model instance was created. |
| 19 | + |
| 20 | + from django.db import models |
| 21 | + from psqlextra.models import PostgresModel |
| 22 | + from psqlextra import signals |
| 23 | + |
| 24 | + class MyModel(PostgresModel): |
| 25 | + myfield = models.CharField(max_length=255, unique=True) |
| 26 | + |
| 27 | + def on_create(sender, **kwargs): |
| 28 | + print('model created with pk %d' % kwargs['pk']) |
| 29 | + |
| 30 | + signals.create.connect(MyModel, on_create, weak=False) |
| 31 | + |
| 32 | + # this will trigger the signal |
| 33 | + instance = MyModel(myfield='cookies') |
| 34 | + instance.save() |
| 35 | + |
| 36 | + # but so will this |
| 37 | + MyModel.objects.create(myfield='cheers') |
| 38 | + |
| 39 | +## psqlextra.signals.update |
| 40 | +Send **after** a new model instance was updated. |
| 41 | + |
| 42 | + from django.db import models |
| 43 | + from psqlextra.models import PostgresModel |
| 44 | + from psqlextra import signals |
| 45 | + |
| 46 | + class MyModel(PostgresModel): |
| 47 | + myfield = models.CharField(max_length=255, unique=True) |
| 48 | + |
| 49 | + def on_update(sender, **kwargs): |
| 50 | + print('model updated with pk %d' % kwargs['pk']) |
| 51 | + |
| 52 | + signals.update.connect(MyModel, on_update, weak=False) |
| 53 | + |
| 54 | + # for every row that is affected, the signal will be send |
| 55 | + MyModel.objects.filter(myfield='cookies').update(myfield='cheers') |
| 56 | + |
| 57 | +## psqlextra.signals.delete |
| 58 | +Send **before** a new model instance is deleted. |
| 59 | + |
| 60 | + from django.db import models |
| 61 | + from psqlextra.models import PostgresModel |
| 62 | + from psqlextra import signals |
| 63 | + |
| 64 | + class MyModel(PostgresModel): |
| 65 | + myfield = models.CharField(max_length=255, unique=True) |
| 66 | + |
| 67 | + def on_delete(sender, **kwargs): |
| 68 | + print('model deleted with pk %d' % kwargs['pk']) |
| 69 | + |
| 70 | + signals.delete.connect(MyModel, on_update, weak=False) |
| 71 | + |
| 72 | + # for every row that is affected, the signal will be send |
| 73 | + MyModel.objects.filter(myfield='cookies').delete() |
| 74 | + |
| 75 | + # in this case, a single row is deleted, the signal will be send |
| 76 | + # for this particular row |
| 77 | + MyModel.objects.get(id=1).delete() |
0 commit comments