I’m proceeding in my quest to learn how to create a Django application using Pinax as a base. I’m writing a sample paste bin application called Oxybeles. It’s main feature will be the ability to send pasted items to another user and to receive new pasted items as responses.
I want a user to be notified when another user sends an item or responds to one. So I went looking how the applications integrated into Pinax do that. For instance, the Inbox feature in Pinax can be used to send a message to another website user:

The Propose Swap feature of the Swaps application will also notify another user:

Those notifications can be seen in the Notices feature of the Inbox:

By inspecting the source code for these features, I found out that they use the django-notification app. There is some documentation about it on the Pinax project website. So, I started following it.
Creating notice types
Following samples and documentation, I created the file apps/oxybeles/management.py that creates notice types at syncdb time:
from django.db.models import signals, get_app
from django.utils.translation import ugettext_noop as _
from django.core.exceptions import ImproperlyConfigured
try:
notification = get_app('notification')
def create_notice_types(app, created_models, verbosity, **kwargs):
notification.create_notice_type(
"pasteditem_received",
_("Pasted Item Received"),
_("you have received a pasted item"))
notification.create_notice_type(
"pasteditem_sent",
_("Pasted Item Sent"),
_("you sent a pasted item"))
signals.post_syncdb.connect(create_notice_types, sender=notification)
except ImproperlyConfigured:
print "Skipping creation of NoticeTypes as notification app not found."
Then I ran syncdb:
$ python manage.py syncdb Created pasteditem_received NoticeType Created pasteditem_sent NoticeType
Notification templates
Then I created the templates that will be used to format the notifications. Each set is composed by three files: short.txt, full.txt and notice.html. For each notification type I created a directory under apps/oxybeles/templates/notification. For instance:
apps/oxybeles/templates/notification/pasteditem_received/full.txt:
{% load i18n %}{% blocktrans with pasted_item.get_absolute_url as pasted_item_url %}
{{ sender }} sent you a pasted item:
http://{{ current_site }}{{ pasted_item_url }}{% endblocktrans %}
apps/oxybeles/templates/notification/pasteditem_sent/notice.html:
{% load i18n %}
{% blocktrans with pasted_item.get_absolute_url as pasted_item_url %}
You sent a <a href="{{ pasted_item_url }}">pasted item</a> to {{ recipient }}.
{% endblocktrans %}
Sending notification
After that I should be able to notify a user when someone sends a pasted item. The first step is to add an appropriate field to the pasted item detail template:
templates/oxybeles/pasteditem_detail.html:
...
<h1>Pasted Item</h1>
<pre>
<p>{{ object.text }}</p>
</pre>
<div id="basic-form">
<fieldset>
<legend>{% trans "Send Item" %}</legend>
<form id="pastebin_send_form" method="POST" action="">
<div>{{ form.non_field_errors }}</div>
<div>{{ form.recipient.errors }}</div>
<div>Send to another user: {{ form.recipient }}</div>
<div><input type="submit" value="send" class="button" /></div>
<input type="hidden" name="action" value="send" />
<input type="hidden" name="uuid" value="{{ object.uuid }}" />
</form>
</fieldset>
</div>
...
And a form to deal with the submitted data:
In apps/oxybeles/forms.py:
...
class SendItemForm(forms.Form):
uuid = forms.CharField(max_length=36)
recipient = forms.CharField(max_length=30)
...
The view that shows a pasted item now will also act on this form’s data:
In apps/oxybeles/views.py:
...
def detail(request, uuid, form_class=SendItemForm, template_name='oxybeles/pasteditem_detail.html'):
form = form_class()
if request.method == 'POST':
if request.POST["action"] == "send":
form = form_class(sender=request.user, data=request.POST)
if form.is_valid():
form.save()
request.user.message_set.create(
message=ugettext("The pasted item was sent."))
url = form.pasted_item.get_absolute_url()
return HttpResponseRedirect(url)
pasted_item = get_object_or_404(PastedItem, uuid=uuid)
return render_to_response(template_name,
{ 'object': pasted_item, 'form': form },
context_instance=RequestContext(request))
detail = login_required(detail)
...
The form.save() function will notify the recipient and also the sender.
In apps/oxybeles/forms.py:
...
def save(self):
self.pasted_item = self.cleaned_data['uuid']
self.recipient_user = self.cleaned_data['recipient']
if notification:
notification.send([self.sender], "pasteditem_sent",
{'pasted_item': self.pasted_item,
'recipient': self.recipient_user,})
notification.send([self.recipient_user], "pasteditem_received",
{'pasted_item': self.pasted_item,
'sender': self.sender,})
...
django-notification does all the work. It creates the notifications and will also mail the user if the preference is enabled. The email will only be sent when we run manage.py send_mail, though.
Now I can send a pasted item I’m seeing:

Those sendings are recorded as notifications:
![]()
And the recipient is notified when someone sends an item:
![]()
Pinax is an integrated collection of selected reusable Django apps, and I’m starting to learn how to leverage it. Seems pretty nice so far.
The code for this article is hosted at GitHub. Feedback is welcome.
Thanks for posting this! I was having lots of trouble overriding the default notice.html templates, because I couldn’t figure out where the customized templates needed to go.
Comment by Mitch — January 14, 2009 @ 7:13 pm
Hi!
Thanks for posting, I’m currently trying to understand how does the notification framework work. Can you tell me is there any way to add my own notification backends to this plugin? I mean, I need to notify people using SMS messages, but don’t know if this is possible using the plugin…
Andrzej
Comment by Andrzej — January 30, 2009 @ 6:08 pm
Yes, thanks a lot.
Comment by clarisssa — October 10, 2009 @ 1:40 pm
templates are missed on GitHub:(
Comment by stas — November 25, 2009 @ 10:02 am