Fernando Correia’s Weblog

November 8, 2008

Exploring Pinax – Part 7

Filed under: Software Development — Fernando Correia @ 8:22 am
Tags: ,

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:

Sending a pasted item

Those sendings are recorded as notifications:

Item sent notification

And the recipient is notified when someone sends an item:

Item received notification

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.

About these ads

4 Comments »

  1. 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

  2. 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

  3. Yes, thanks a lot.

    Comment by clarisssa — October 10, 2009 @ 1:40 pm

  4. templates are missed on GitHub:(

    Comment by stas — November 25, 2009 @ 10:02 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: