You want to create Django template/client side logic capable of receiving automatic updates (i.e. without user action) when something changes on Django's back end/server side (e.g. new record is created).
For Django install the Python
socketIO-client package to communicate with Node.js/Socket.IO. Use the
|Backing source code available|
The backing source code for the application described next is available at https://github.com/drubio/djangorecipes.
Figure 1 illustrates the architecture/workflow for the implementation described in the remainder of this recipe, which is to enable real-time updates for a Django application with Node.js.
The first step to use Django with Node.js is to install the Python
socketIO-client package (e.g.
pip install socketIO-client). The
socketIO-client package is the Python library needed to communicate with Socket.IO which is a Node.js framework. This is the only Python package that you'll need to create the design illustrated in figure 1.
Once you install the required Python package, I recommend you create a variable in
settings.py to define the location where Node.js will run, like
NODEJS_SOCKET_URL = 'http://localhost:3000'. Alternatively you can hardcode the Node.js location in your Django code, but I recommend you use this type of variable because it makes future changes easier.
Next, let's take a look at the Django model that interacts with Node.js via Socket.IO. Listing 1 illustrates this model.
The Django model in listing 1 is pretty basic, except for the fact that it uses custom logic in its
save method. As illustrated in previous recipes, by overriding a Django model's
save method you can provide custom logic besides the default behavior of saving the record to the database. In the case of listing 1, we first check the instance
pk value, if it doesn't exist it means it's a new record and so we first communicate the record to Node.js. Note that you can place the Node.js/Socket.IO logic anywhere in your Django project, but in this case I opted to use a model's save() method because it's handy location so that irrespective of where the
Special record is created, the
save takes care of always triggering the same Node.js logic.
The first part of the Node.js/Socket.IO logic in listing 1 is to parse the URL endpoint defined in the
NODEJS_SOCKET_URL variable from
settings.py -- if you didn't define a variable for this purpose you can hardcode the Node.js location here. Next, we simply use the
emit method from Socket.IO to publish the record to Node.js, where the first argument
admindailyspecials represents the namespace/channel to send the data and the second argument is a JSON representation of the record. Finally, a call is made to the
save method using
super so the record maintains its default behavior of saving the record to the database.
Summarizing, listing 1 achieves steps 5 and 6 in figure 1, where each time a new
Special record is created in Django it's also sent to Node.js on the
The first step in listing 2 is to give the web page access to the Socket.IO library installed in Node.js -- note the template has access to the
NODEJS_SOCKET_URL variable in
settings.py. The second step in listing 2 is to establish a connection to Node.js via Socket.IO with
Once the Node.js connection is established, the
socket.on method indicates that when the
dailyspecials namespace/channel emits a message it be processed with the following logic: it first outputs the message to the browser console and if the message has the
special attribute it prepends the message in an HTML format to the
special-list element -- note this last snippet relies on jQuery to do the prepend operation.
To give you a better idea of the user interface associated with listing 2, figure 2 illustrates the
The feed on the right hand-side of figure 2 (i.e. the
special-list element) is automatically updated every time data is published to the Node.js
dailyspecials namespace/channel receives messages that are associated with the
admindailyspecials namespace/channel which are triggered when a new Django model
Special record is created -- this last sequence might sound confusing, but it will become clearer in the next section that describes the Node.js setup and application design.
To set up Node.js in this application you'll need to install the Socket.IO package (e.g.
npm install socket.io) and Express package (e.g.
npm install express). Although we'll use minimal parts of these last Node.js packages, they make it easier to get up and running with Node.js, as well as make the Node.js design more understandable. Listing 3 illustrates the Node.js app that integrates with the previous Django snippets.
The first three lines in listing 3 create a Node.js server relying on the Express package and also imports the Socket.IO package. Next, the
server.listen line configures Node.js to listen on port 3000. Then you can see the
io.on method executes a series of steps when Node.js receives a connection. The first step is to output a connection message to the server side console. Next, it emits a welcome-type JSON message to all clients listening on the
Next, when the Node.js server receives a message on the
admindailyspecials namespace/channel -- which is the same channel used by the Django model
save method in listing 1 -- it outputs a connection message to the server side console and in addition, broadcasts the message out to all clients listening on the
After you place the contents of listing 3 in a file named
app.js and start it up with Node.js (e.g.
node app.js), a Django application using the design from listings 1 and 2 is capable of receiving real-time updates.