12 November 2011

I recently ran into a situation helping someone figure out how to execute a Python script and display the contents within a Django template. While his initial thought was to embed the entire script as Python code in an HTML template, a more elegant solution would be to simply run the script server-side and display the results using AJAX.



Note: I won't go into how to include Dojo in your templates (all depends on your setup), so I'll assume everything is already setup the way it should be.

For a simple example, let's say you have the following Python script:
print "Hello, world!"
We'll first specify a URL that we can call just for AJAX purposes by editing urls.py:
urlpatterns = patterns('',
    url(r'^ajax', 'myproject.myapp.views.ajax'),
    ...
)
Note that I inserted this line before all other lines - I want to be completely sure that my AJAX call never gets redirected somewhere else, since this file is read and processed by Django in order, from top to bottom. Doing this ensures that my AJAX call gets matched correctly each and every time.
Second, you'll need to create a view in Django that will run the script and return the output:
import os
from django.http import HttpResponse
...
def ajax(req):
    if req.is_ajax():
        stdout = os.popen("/path/to/script.py")
        output = stdout.read()
        return HttpResponse(output)
We named the function "ajax", to correspond with "myproject.myapp.views.ajax" in the urls.py file. After all, urls.py simply tells Django what view to call. We also check to make sure that this view is being called via AJAX only in order to continue. The view then runs the desired Python script using the "os.popen()" function and assigns the output to the variable stdout.

A quick note about os.popen(): You need to specify the full path to the script here. If you don't, Django will look in the main project directory (assuming your urls.py definition has placed you there). Better to be sure and use an absolute path.

Once we've run the script, we read the output and assign it to the variable... output (I know, I'm so clever). Then, we return that data using HttpResponse. Remember that we're making a request over HTTP to get this information - we can't just use "return output", because the browser expects headers that HttpResponse provides.

Finally, let's write our AJAX code.  Since templates can really be anything, I'll just assume that we have a div with id="results", where we will display the output:
var myResults = dojo.byId("results")

dojo.xhrGet({
    url: "/ajax",
    load: function (data) {
        myResults.innerHTML = data;
    }
});
The page element that will display our script output is assigned to myResults. Then, we use the "dojo.xhrGet()" function to make an AJAX call as a GET request. The URL we request is "/ajax" (remember what we placed in urls.py), and the response (the script output) is placed into our div to be shown on the page.

If all worked correctly, you should be looking at "Hello, world!" somewhere on the page. This tutorial should get you started, and give you a good idea as to how AJAX works in Django.
Categories:

0 comments:

Post a Comment