<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mattdorn.com &#187; javascript</title>
	<atom:link href="http://www.mattdorn.com/content/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mattdorn.com</link>
	<description>Generously funded by Matt Dorn</description>
	<lastBuildDate>Sun, 07 Feb 2010 00:07:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>RESTful Web apps with Django, Piston and Ext JS</title>
		<link>http://www.mattdorn.com/content/restful-web-apps-with-django-piston-and-ext-js/</link>
		<comments>http://www.mattdorn.com/content/restful-web-apps-with-django-piston-and-ext-js/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 22:52:28 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[ext-js]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://www.mattdorn.com/?p=77</guid>
		<description><![CDATA[Piston appears to have emerged as the preferred method for giving your Django applications a RESTful API.  While there are any number interesting things you might want to want to do with such an API, this post is about using it to give your Django app an attractive, Ajax-y, Ext JS interface.]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p><a class="reference" href="http://bitbucket.org/jespern/django-piston/wiki/Home">Piston</a> appears to have emerged as the preferred method for giving your <a class="reference" href="http://www.djangoproject.com/">Django</a> applications a <a class="reference" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</a> API.  While there are any number interesting things you might want to want to do with such an API, this post is about using it to give your Django app an attractive, <a class="reference" href="http://en.wikipedia.org/wiki/Ajax_(programming)">Ajax-y</a>, <a class="reference" href="http://www.extjs.com/">Ext JS</a> interface.</p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#getting-started" id="id1" name="id1">Getting Started</a></li>
<li><a class="reference" href="#piston-basics" id="id2" name="id2">Piston Basics</a></li>
<li><a class="reference" href="#basics-of-ajax-with-ext-js" id="id3" name="id3">Basics of Ajax with Ext JS</a></li>
<li><a class="reference" href="#using-ext-js-widgets" id="id4" name="id4">Using Ext JS Widgets</a></li>
<li><a class="reference" href="#extending-piston" id="id5" name="id5">Extending Piston</a><ul>
<li><a class="reference" href="#custom-emitters" id="id6" name="id6">Custom Emitters</a></li>
<li><a class="reference" href="#overriding-handler-methods" id="id7" name="id7">Overriding Handler Methods</a></li>
</ul>
</li>
<li><a class="reference" href="#conclusion" id="id8" name="id8">Conclusion</a></li>
</ul>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id1" id="getting-started" name="getting-started">Getting Started</a></h2>
<p>I&#8217;m going to proceed with two assumptions: 1) You&#8217;ve got a Django project up and running, and 2) You&#8217;ve installed the django-piston package (as in <tt class="docutils literal"><span class="pre">easy_install</span> <span class="pre">django-piston</span></tt>).  If you&#8217;re just getting started with Django, the official <a class="reference" href="http://docs.djangoproject.com/en/dev/intro/tutorial01/">tutorial</a> is a great place to start.  Additionally, you may want to take advantage of <a class="reference" href="http://pypi.python.org/pypi/virtualenv">virtualenv</a> for managing Python packages used by your application.</p>
<p>From there, you&#8217;ll need to install the Ext JS library.  In order to develop your Django app using JavaScript, you&#8217;ll need to put your JavaScript files in a media directory which will be handled differently from your other application files.  In the root of my project directory, I have a directory called <tt class="docutils literal"><span class="pre">media</span></tt> where static files such as images, CSS, and JavaScript files will be stored.  To make use of this directory in development, take a look at &quot;<a class="reference" href="http://docs.djangoproject.com/en/dev/howto/static-files/">How to serve static files</a>&quot;, available on the Django documentation site.</p>
<p>So, download <a class="reference" href="http://www.extjs.com/products/extjs/download.php">the latest version of Ext JS</a>, and extract it into a place that makes sense in your static media folder.  In my Django project, the relevant part of my directory structure looks like this:</p>
<pre class="literal-block">
myproject/
    media/
        css/
        img/
        js/
            ext/
    todos/
        models.py
        [etc...]
</pre>
<p>You&#8217;ll probably want to remove the version number from the name of the root Ext JS directory, as I&#8217;ve done here.</p>
<p>Note that I&#8217;ve included my <tt class="docutils literal"><span class="pre">todos</span></tt> Django application in this listing, since in this tutorial we&#8217;ll be using a &quot;to-do&quot; list application to illustrate the tools under consideration.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id2" id="piston-basics" name="piston-basics">Piston Basics</a></h2>
<p>Before we do anything with Ext JS, let&#8217;s make make sure we have a basic understanding of how Piston interacts with your Django application.</p>
<p>My application has a single, very simple model, representing an item on a to-do list.</p>
<p>So, my <tt class="docutils literal"><span class="pre">models.py</span></tt> in its entirety looks like this:</p>
<pre class="literal-block">
from django.db import models

class Task(models.Model):
    name = models.CharField(max_length=50)
    complete = models.BooleanField(default=False, null=False)

    def __unicode__(self):
        return self.name
</pre>
<p>What we want to do is expose this model via a RESTful API, which is exactly what Piston will enable us to do.  Most of what follows does not deviate significantly from what you&#8217;ll find in the <a class="reference" href="http://bitbucket.org/jespern/django-piston/wiki/Documentation#piston-documentation">Piston documentation</a>.</p>
<p>First, create an <tt class="docutils literal"><span class="pre">api</span></tt> directory in your project&#8217;s root.  At a minimum, you will need <tt class="docutils literal"><span class="pre">__init__.py</span></tt>, but also <tt class="docutils literal"><span class="pre">urls.py</span></tt> and <tt class="docutils literal"><span class="pre">handlers.py</span></tt>.  Let&#8217;s look at <tt class="docutils literal"><span class="pre">handlers.py</span></tt> first.</p>
<p>Here is where you need to do the minimal work of associating one of your project&#8217;s models with a Piston &quot;handler&quot; class that will define how basic <a class="reference" href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> operations are handled in your application:</p>
<pre class="literal-block">
from piston.handler import BaseHandler
from myproject.todos.models import Task

class TaskHandler(BaseHandler):
    model = Task
</pre>
<p>In <tt class="docutils literal"><span class="pre">urls.py</span></tt>, you&#8217;ll find a configuration very similar to what you need to do to connect your regular Django views with URLs to access them:</p>
<pre class="literal-block">
from django.conf.urls.defaults import *
from piston.resource import Resource
from piston_demo.api.handlers import TaskHandler

task_resource = Resource(TaskHandler)

urlpatterns = patterns('',
   url(r'^tasks/(?P&lt;id&gt;\d+)$', task_resource),
   url(r'^tasks$', task_resource),
)
</pre>
<p>Here the url pattern takes a Piston <tt class="docutils literal"><span class="pre">Resource</span></tt>  as an argument, which in turn takes the Piston &quot;handler&quot; class that we just defined.</p>
<p>With this minimum bit of work, our to-do list app has a basic RESTful API.  Below is an example of posting data from the command line using cURL:</p>
<pre class="literal-block">
mdorn&#64;ubuntu:~$ curl -i -H &quot;Accept: application/json&quot; -X POST -d &quot;name=To-do%20#1&amp;complete=false&quot; http://ubuntu:8000/api/tasks
HTTP/1.0 200 OK
Date: Sun, 20 Dec 2009 18:48:53 GMT
Server: WSGIServer/0.1 Python/2.5.2
Vary: Authorization
Content-Type: application/json; charset=utf-8

{
    &quot;name&quot;: &quot;To-do #1&quot;,
    &quot;complete&quot;: &quot;true&quot;
}
</pre>
<p>After posting a second to-do item, if we perform a <tt class="docutils literal"><span class="pre">GET</span></tt> request against the resource&#8217;s URL, we&#8217;ll see:</p>
<pre class="literal-block">
mdorn&#64;ubuntu:~$ curl -i -X GET http://ubuntu:8000/api/tasks
HTTP/1.0 200 OK
Date: Sun, 20 Dec 2009 18:50:40 GMT
Server: WSGIServer/0.1 Python/2.5.2
Vary: Authorization
Content-Type: application/json; charset=utf-8

[
    {
        &quot;name&quot;: &quot;To-do #1&quot;,
        &quot;complete&quot;: false
    },
    {
        &quot;name&quot;: &quot;To-do #2&quot;,
        &quot;complete&quot;: false
    }
]
</pre>
<p>We can also delete and update by using the <tt class="docutils literal"><span class="pre">DELETE</span></tt> and <tt class="docutils literal"><span class="pre">PUT</span></tt> HTTP verbs, respectively.</p>
<p>Two things to note here: 1) The default MIME type for Piston responses is JSON. 2) If we want the list of returned records to include the record&#8217;s primary key, we&#8217;d need to explicitly specify it in our handler definition:</p>
<pre class="literal-block">
class TaskHandler(BaseHandler):
    fields = ('id', 'name', 'complete')
    model = Task
</pre>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id3" id="basics-of-ajax-with-ext-js" name="basics-of-ajax-with-ext-js">Basics of Ajax with Ext JS</a></h2>
<p>Next we&#8217;ll take a look at the Ajax functionality provided by Ext JS, and how to connect it with our Django app.  Create an HTML template in your Django app that looks like this:</p>
<pre class="literal-block">
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Basic Example&lt;/title&gt;

    &lt;!-- Include Ext and app-specific scripts: --&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;/static/js/ext/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;/static/js/ext/ext-all-debug.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;/static/js/basic.js&quot;&gt;&lt;/script&gt;

    &lt;!-- Include Ext/app-specific stylesheets here: --&gt;
    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/js/ext/resources/css/ext-all.css&quot; /&gt;
    &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/css/basic.css&quot; /&gt;

&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Basic Ext JS Ajax Example&lt;/h1&gt;

    &lt;div id=&quot;content&quot;&gt;
            &lt;div id=&quot;myDiv&quot;&gt;Watch this space.&lt;/div&gt;
            &lt;input type=&quot;button&quot; id=&quot;myButton&quot; value=&quot;Click me&quot; /&gt;
    &lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>I&#8217;ll assume you can wire this template up to your <tt class="docutils literal"><span class="pre">urls.py</span></tt> on your own, using <tt class="docutils literal"><span class="pre">direct_to_template</span></tt>, since we won&#8217;t be using any application view.</p>
<p>Note that in addition to the Ext JS and CSS files being referenced, you&#8217;ll need basic.js:</p>
<pre class="literal-block">
Ext.onReady(function() {
    var buttonClicked = function() {
        Ext.Ajax.defaultHeaders = {
            'Accept': 'application/json'
        };
        var resp = Ext.Ajax.request({
            url: '/api/tasks',
            method: 'GET',
            success: function(resp) {
                var item = Ext.decode(resp.responseText)[0].name;
                var myDiv = Ext.get('myDiv');
                myDiv.update('The first item in the to-do list is: &lt;br /&gt;' + item);
            },
            failure: function() {
                Ext.Msg.alert('Failed');
            },
        });

    }
    Ext.get('myButton').on('click', buttonClicked);
});
</pre>
<p>Optionally, the CSS that&#8217;s in <tt class="docutils literal"><span class="pre">basic.css</span></tt> will make this demo a bit prettier.  I won&#8217;t list the source here, but it&#8217;s in the download for this tutorial (see below).</p>
<p>Now when you navigate to the URL that renders the template in your browser, the code in <tt class="docutils literal"><span class="pre">basic.js</span></tt> executes when the <tt class="docutils literal"><span class="pre">onReady</span></tt> event is fired, which happens when the page is loaded.  Here we&#8217;re defining a callback function to be executed when the button whose <tt class="docutils literal"><span class="pre">id</span></tt> attribute is &quot;myButton&quot;.  The action to be performed is to use an Ext JS DOM manipulation function to replace the contents of the &quot;div&quot; tag with id <tt class="docutils literal"><span class="pre">myDiv</span></tt> with a response from the server, in this case the first item we added to our to-do list using our new RESTful API.</p>
<p>Note that once you start working with Ext JS widgets, you won&#8217;t often use the <tt class="docutils literal"><span class="pre">Ext.Ajax</span></tt> class, as the widgets generally abstract it away for you.  If you&#8217;re new to Ext JS, I recommend taking a look at the the <a class="reference" href="http://www.extjs.com/learn/Tutorial:Introduction_to_Ext_2.0">Introduction to Ext 2.0</a> tutorial, to get a better of understanding of what&#8217;s going on here.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id4" id="using-ext-js-widgets" name="using-ext-js-widgets">Using Ext JS Widgets</a></h2>
<p>Now let&#8217;s look at how Ext JS&#8217;s <a class="reference" href="http://www.extjs.com/deploy/dev/examples/restful/restful.html">RESTful store</a> and grid widget can interface with our Django to-do list app to give it a very attractive and responsive Ajax interface.</p>
<p>I won&#8217;t list most of the source code for the widget here, but you can find it in the <a class="reference" href="#conclusion">Conclusion</a> below.</p>
<p>To populate the grid with our to-do list, our <tt class="docutils literal"><span class="pre">Ext.data.Store</span></tt> instance will need an <tt class="docutils literal"><span class="pre">Ext.data.HttpProxy</span></tt> object pointing to our resource&#8217;s URL:</p>
<pre class="literal-block">
var proxy = new Ext.data.HttpProxy({
    url: '/api/tasks'
});
</pre>
<p>After we define which columns should be included in the grid and set a few other attributes, that should be all we need to instantiate the grid and populate it.</p>
<p>But it doesn&#8217;t populate.  What&#8217;s wrong?  If we open <a class="reference" href="http://getfirebug.com/">Firebug</a> to take a look at the response when we load the grid, we see the following:</p>
<pre class="literal-block">
[
    {
        &quot;name&quot;: &quot;To-do #2&quot;,
        &quot;complete&quot;: true
    },
    {
        &quot;name&quot;: &quot;To-do #1&quot;,
        &quot;complete&quot;: true
    }
]
</pre>
<p>This may be the expected result based on our experiments above, but the problem is that the Grid is expecting the response to be formatted in a different way.  Specifically it expects a JSON dictionary which includes this array of dictionaries as a value assigned to the <tt class="docutils literal"><span class="pre">data</span></tt> key, like so:</p>
<pre class="literal-block">
{
    &quot;data&quot;: [
        {
            &quot;id&quot;: 2,
            &quot;name&quot;: &quot;Take out the trash&quot;,
            &quot;complete&quot;: true
        },
        {
            &quot;id&quot;: 3,
            &quot;name&quot;: &quot;Another try&quot;,
            &quot;complete&quot;: false
        }
    ],
    &quot;success&quot;: true,
    &quot;message&quot;: &quot;&quot;,
}
</pre>
<p>As we can see, it also expects a <tt class="docutils literal"><span class="pre">success</span></tt> flag, and a <tt class="docutils literal"><span class="pre">message</span></tt>, if any.</p>
<p>Fortunately, Piston can be extended to accommodate this requirement.  Let&#8217;s take a look at how to do that.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id5" id="extending-piston" name="extending-piston">Extending Piston</a></h2>
<div class="section">
<h3><a class="toc-backref" href="#id6" id="custom-emitters" name="custom-emitters">Custom Emitters</a></h3>
<p>Here we&#8217;ll introduce a new file to the <tt class="docutils literal"><span class="pre">api</span></tt> folder that contains our Piston configuration, <tt class="docutils literal"><span class="pre">emitters.py</span></tt>.  Earlier, without realizing it we were making use of Piston&#8217;s default &quot;emitter&quot; for returning responses.  We need to define and register a custom emitter class to return data in a format understood by our Ext JS widget(s):</p>
<pre class="literal-block">
from django.utils import simplejson
from django.core.serializers.json import DateTimeAwareJSONEncoder

from piston.emitters import Emitter

class ExtJSONEmitter(Emitter):
    &quot;&quot;&quot;
    JSON emitter, understands timestamps, wraps result set in object literal
    for Ext JS compatibility
    &quot;&quot;&quot;
    def render(self, request):
        cb = request.GET.get('callback')
        ext_dict = {'success': True, 'data': self.construct(), 'message': 'Something good happened on the server!'}
        seria = simplejson.dumps(ext_dict, cls=DateTimeAwareJSONEncoder, ensure_ascii=False, indent=4)

        # Callback
        if cb:
            return '%s(%s)' % (cb, seria)

        return seria

Emitter.register('ext-json', ExtJSONEmitter, 'application/json; charset=utf-8')
</pre>
<p>Notice that in registering this emitter, we&#8217;ve given it the title <tt class="docutils literal"><span class="pre">ext-json</span></tt>.  We&#8217;ll now need to modify our <tt class="docutils literal"><span class="pre">api/urls.py</span></tt> to pass this information as well:</p>
<pre class="literal-block">
urlpatterns = patterns('',
   url(r'^tasks/(?P&lt;id&gt;\d+)$', task_resource,  {'emitter_format': 'ext-json'}),
   url(r'^tasks$', task_resource, {'emitter_format': 'ext-json'}),
)
</pre>
<p>With those simple changes, we can now reload our grid and see it populated with our to-do list.</p>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id7" id="overriding-handler-methods" name="overriding-handler-methods">Overriding Handler Methods</a></h3>
<p>However, we run into a similar problem when POSTing data to create a new to-do item or update an existing item.  The Ext JS widget sends a request containing a single POST variable called <tt class="docutils literal"><span class="pre">data</span></tt> containing a JSON-formatted dictionary of the values to be posted.  Piston expects a dictionary containing key-value pairs that map directly onto the fields in our model.</p>
<p>Here we can override the methods of our <tt class="docutils literal"><span class="pre">BaseHandler</span></tt>-derived class in <tt class="docutils literal"><span class="pre">handlers.py</span></tt> to deal with this unfortunate turn of events:</p>
<pre class="literal-block">
class TaskHandler(BaseHandler):
    fields = ('id', 'name', 'complete')
    model = Task

    def create(self, request, *args, **kwargs):
        if not self.has_model():
            return rc.NOT_IMPLEMENTED

        attrs = self.flatten_dict(request.POST)
        if attrs.has_key('data'):
            ext_posted_data = simplejson.loads(request.POST.get('data'))
            attrs = self.flatten_dict(ext_posted_data)

        try:
            inst = self.model.objects.get(**attrs)
            return rc.DUPLICATE_ENTRY
        except self.model.DoesNotExist:
            inst = self.model(**attrs)
            inst.save()
            return inst
        except self.model.MultipleObjectsReturned:
            return rc.DUPLICATE_ENTRY
</pre>
<p>Note that this is mostly a copy of the default implementation of the method with the exception of the three lines of code following <tt class="docutils literal"><span class="pre">if</span> <span class="pre">attrs.has_key('data'):</span></tt>, inclusive.</p>
<p>If we do something similar to the <tt class="docutils literal"><span class="pre">update</span></tt>, method, our application is now able to create and update records when the widget POSTs or PUTs data.</p>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id8" id="conclusion" name="conclusion">Conclusion</a></h2>
<p>You can <a class="reference" href="http://media.textmethod.com/downloads/piston_ext_demo.tar.gz">download the source code</a> referenced in this tutorial.  It&#8217;s a complete Django app; you&#8217;ll just need to <tt class="docutils literal"><span class="pre">syncdb</span></tt> and install Ext JS as explained above.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/restful-web-apps-with-django-piston-and-ext-js/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
