March 19, 2016

Today I had to get django-postman messages to work with django-notifications. There was no useful information out there, so maybe this will be helpful to someone. Modern Django apps would use the Signals, but Django Postman is pretty old.

Reading the source is better than reading StackOverflow!

Also, here as a Gist.

"""Handle notification signals from django-postman and pass
them to django-notifications. Postman does not """


# In the app's models.py:

from django.contrib.auth.models import User

from notifications.signals import notify

def send(users=[], label='', extra_context={}):
    if label == 'postman_message':
        msg = extra_context['pm_message']
        user = User.objects.get(pk=msg.sender_id)
        notify.send(user, recipient=users[0], verb='New message', description=msg.subject)

# From postman/utils.py for reference:

name = getattr(settings, 'POSTMAN_NOTIFIER_APP', 'notification')
if name and name in settings.INSTALLED_APPS:
    name = name + '.models'
    notification = import_module(name)
else:
    notification = None

# ...so django-postman takes the name of an app and concats '.models' to in and then tries
# to load that module. Then in the function below, it expects notificationapp.models to
# have a function 'send()', but django-notifications doesn't work that way. So we intercept
# the notification and send the correct data to notify.send().

def notify_user(object, action, site):
    """Notify a user."""
    if action == 'rejection':
        user = object.sender
        label = 'postman_rejection'
    elif action == 'acceptance':
        user = object.recipient
        parent = object.parent
        label = 'postman_reply' if (parent and parent.sender_id == object.recipient_id) else 'postman_message'
    else:
        return
    if notification:
        # the context key 'message' is already used in django-notification/models.py/send_now() (v0.2.0)
        notification.send(users=[user], label=label, extra_context={'pm_message': object, 'pm_action': action})
    else:
        if not DISABLE_USER_EMAILING and user.email and user.is_active:
            email('postman/email_user_subject.txt', 'postman/email_user.txt', [user.email], object, action, site)

---

If you want to read more, subscribe to my personal newsletter.