A lot of websites display notifications in one form or another these days. Facebook shows the new message notification, Gmail have the new mail notifications (with the support of browser notifications).
I was asked today how hard it would be to implement a real-time notification system. The answer, as it turns out, is: not very hard at all.
It was in fact so easy that I decided to write up this blog post on the subject to show how to implement a simple notification system in a Django app.
This has been tested with Django 1.6.8 and 1.7.1, and python 2.7.4 and python 3.4, with the following browsers:
Note: you need redis-server running. If you don't have Redis installed see redis.io, or use your default package manager to install it.
You can download the full source code here.
This could easily be implemented in an existing application but since I'm doing this from scratch I'll go through the steps of setting everything up.
First step is to install
The next thing is to create a new project.
That's our project files and directories setup. Now we add paths to
settings.py for the static files and html templates. Open
notifications/settings.py in a text editor and add the following
Make sure you add
INSTALLED_APPS as well.
This tells Django where to find our static resources and templates.
That's all we need to do for our setup step.
We store the notification as a model. This way we can load existing notification when the user loads the page the first time.
demo/models.py in a text editor and add the following code:
We have yet to create the
NotificationSerializer so we will do that
in the next step.
We add the
SelfPublishModel mixin, so we don't have to worry about
actually publishing the model, as that will happen as soon as it's
created (note: for this post I have omitted handling updates to
The only field on this model is a message field, but you could easily add a title to the notification.
The notifications we are creating here are global, so everyone on the
site will receive them. You could tailor the notifications to be on a
per-user basis by adding a foreign key to the
User model, and using
to subscribe each user to their own notification channels (based on
their username or some other unique identifier).
I will add some notes about this at the end of this post, but for now I will keep it simple.
Add a new file:
demo/serializers.py and open it in a text editor and
add the following code:
We only want to publish the
message field, so we specify this in the
Without routers SwampDragon won't know how to deal with the incoming data.
Create a new file:
demo/routers.py and add the following code:
Since we don't have anything generating notifications, we'll add the
Notification model to django admin so we can create them from there.
demo/admin.py in a text editor and replace the content with the
We want to load existing notifications, and be able to show these notifications even if the SwampDragon server is not responding.
demo/views.py in a text editor and add the following code:
We use a standard Django CBV (class based view) to load the five last
notifications. We set the model to
Notification and specify the
template to be
notifications/urls.py in a text editor and change it to the
Create two new directories:
Create a new html template:
templates/home.html and add the
If you want to run this on anything but the local dev server, see this
on adding a context processor for the
static/notifications.js and add the
Create a database
If you are using Django 1.7+
Create a super user. This is done by either answering "yes" to the
question when you run
migrate. You can do it manually
python manage.py createsuperuser.
Open a new terminal and type:
and another terminal and type:
To test this out, open a web browser to http://localhost:8000. The browser will ask if localhost can have permission to show notifications. If you answer no, you will only see the notifications on the page.
Open another browser window to http://localhost:8000/admin/. Log in and add a new notification instance and you should be able to see the new notification.
As mentioned above, you can have user specific notifications if you use something like swampdragon-auth.
Update the model to the following:
You only have to make a small change to the router by adding
get_subscription_contexts and setting the
decorator on the
Now notifications are user specific (and users who are not signed in can simply not subscribe).
The example code for this post is available at https://github.com/wildfish/swampdragon-django-notifications-demo
The GOV.UK Design System is a toolkit and a set of guidelines for creating sites and services for Her Majesty's Government which are clear and consistent and accessible.
MangoPay presents itself as "Payments for Marketplaces", but it's far from being just a payment provider...