Getting Started¶
Installation¶
The Demo¶
While you’re welcome to use the setup instructions here, it may be easier to just try out the demo that comes with this package. The demo doesn’t cover all the use cases (yet) but it does cover most of the standard stuff.
Registering the Models¶
The process of issuing and routing notifications in Django Vox happens in 4 steps.
- Notification definitions: These definitions are registered, and attached to specific models.
- Recipients: Any given notification can have 4 possible recipients.
- The model that the notification is attached to
- The actor of the notification (optional)
- The target of the notification (optional)
- The site contacts (these come built-in)
- Channels: Additionally, each of these recipients can have zero, 1, or multiple “channels”. For example, a User model might have one channel for the user themselves, one for the user’s followers, and one for the user’s emergency contact.
- Contact: A contact specifies the actual address that a the notifications are sent to. Any model specified in a channel, should also define contacts in its registration, otherwise that recipient won’t have any way of receiving the notifications.
Any model that will be either issuing notifications, or receiving them should have a registration. It might look something like this:
from django.db import models
from django_vox.registry import (VoxRegistration, Notification,
Channel, objects, provides_contacts)
class User(models.Model):
# required email, optional mobile_phone
email = models.EmailField(blank=False)
mobile_phone = models.CharField(blank=True, max_length=50)
...
class UserVox(VoxRegistration):
@provides_contacts("email")
def email_contact(self, instance, notification):
yield instance.email
@provides_contacts("sms")
def email_contact(self, instance, notification):
if instance.mobile_phone:
yield instance.mobile_phone
def get_channels(self):
return {"": Channel.self(self)}
class PurchaseOrder(models.Model):
customer = models.ForeignKey(User, on_delete=models.PROTECT)
def save(self, *args, **kwargs):
created = self.id is None
if not created:
old = PurchaseOrder.objects.get(pk=self.pk)
else:
old = None
super().save(*args, **kwargs)
objects[type(self)].registration.post_save(
created, old, self)
class PurchaseOrderVox(VoxRegistration):
received = Notification(
_("Notification that order was received."))
on_hold = Notification(
_("Notification that order is on hold."))
def post_save(self, created, old, new):
if created:
self.received.issue(new)
if old and not old.on_hold and new.on_hold:
self.on_hold.issue(new)
def get_channels(self):
return {"cust": Channel.field(PurchaseOrder.customer)}
# the actual registration
objects.add(User, UserVox, regex=None)
objects.add(PurchaseOrder, PurchaseOrderVox, regex=None)
In the above example, you have a User model, which can receive emails, and
optionally an SMS message. You also have purchase orders that have two
notifications registered on them (received
and on_hold
). Whenever
the purchase order is saved, it calls post_save
on the registration object,
and that fires the notifications themselves.
Once you’ve finished adding these, you’ll need to regenerate the
notifications table using the make_notifications
management command:
python3 manage.py make_notifications
And there you have it. Now, in order for this to do anything useful, you’ll need to add some appropriate templates. In this case, you’ll want an email template for the “customer” recipient of the purchase order notifications, and possibly a template for a site contact too.
For more details on model registration and the various options, see the Registrations in Detail page.
One-time Messages from the Admin¶
The normal way to handle notifications is call notification.issue(instance)
from within the code. It’s also possible to manually issue notifications
from the admin as long as a notification doesn’t have an actor/target model.
The other way of sending messages completely bypasses the Notification
models and uses an Admin Action.
In order to send messages this way, you need to add the
django_vox.admin.notify
action to your ModelAdmin
class. It might look
something like this:
from django.contrib import admin
from django_vox.admin import notify
class UserAdmin(admin.ModelAdmin):
actions = (notify, )
admin.site.register(YourUserModel, UserAdmin)
In order for this to work right, the model in question is treated as the channel, and so needs to have contacts registered for the appropriate backend & protocol that you want to use.
Note
Because we don’t actually have a notification model here, a fake
notification (django_vox.models.OneTimeNotification
) is passed
to the contact methods. This can be used if only want
certain contacts to be accessible in this way.