APE, Django, and Signals

In my last post, I built a quick Django application for posting messages, and updating those messages using the Ajax Push Engine (APE). One of the things that bugged me about the design was that the APE update occurred directly in the view that saved the message. That’s fine for the very narrow application as it stands, but what happens if sometime in the future, some other view or method saves messages? You’ll have to duplicate that APE code there too, and duplication is something we want to avoid.

All we really want to do is make sure that whenever Django saves a message, it also spits that message out to any clients listening on the APE channel. Django provides a really easy way to do that with signals. Because I’m lazy, I’ll let the Django docs describe signals to you.

So, this is _really_ easy to implement. You just define the signal handler, then connect it to the post_save signal of the Message model. Like so:

You can just stick that at the bottom of models.py if you’d like.

Now your view for handling message submission is really simple:

And there you have it… Any time you save a message, Django will tell APE, and you can forget all about it.

Comet with Django and APE

Recently I’ve been looking at using the AJAX Push Engine (APE) from Weeyla for adding Comet functionality to a Django site. To get a feel for for how APE works, I threw together a really trivial message posting app, and figured I’d document my process for those who might also be interested in integrating APE with Django. Note: This post assumes you know how to set up a Django project, and know enough about Django to realize this code is missing lots of really important bits (validation, authentication, etc…). This is going to be a short novel of a blog post, with a lot of code, so bear with me…

So, to start with, I just slapped together a really basic message posting app. Just a message with a name and a timestamp.

And here’s the template:

Ok, so that’s the basic setup… Pretty boring, right? If Sue submits a message, Bob has to refresh his page to see it. So, we’re going to add APE into the mix to update Bob right away. Getting APE up running it pretty easy, just follow the instructions over at the APE Wiki. We’ll be using APE’s inlinepush server module. Just for good measure we’ll be tossing some jQuery in as well.

So, the basic idea is we need to connect to a APE “channel” which we’ll use to receive updated messages. We’ll use jQuery to send the messages. So let’s start by using jQuery to submit the form, with the following script:

And here are the updated views:

And so with that, we can now submit messages without reloading the page. Any other users, however, would need to refresh to see the new messages. That’s where APE comes in. Here’s the APE client code (along with the updated append_message function):

And here’s the updated view to send new posts to APE:

You’ll notice I’ve added two settings to settings.py:

APE_PASSWORD = 'testpasswd'
APE_SERVER = 'http://ape-test.local:6969/?'

And that’s all there is to it! Like I said earlier, this is a very incomplete application, and a lot of the “boilerplate” work is left as an exercise for the reader. It should be more than enough to get you on your way though. Perhaps in a later post I’ll move the APE update from inside the view to a post_save signal on the model itself. That’s for another time though…

UPDATE: Well, another time is today. Check out this post about adding a signal handler.