In the first part of this series, we set up Django, created a basic Password model and created a RESTful interface for it. In this post, we’re going to set up backbone.js to load our data from our API.
Get the code
Don’t forget you can browse or clone the code from the github repo.
Javascript dependencies
Download the following dependencies and put them into a subdirectory inside a directory managed by Django’s staticfiles app. I’ve used `contrib/backbone`.
- backbone-min.js – core library
- underscore-min.js – backbone dependency
- json2.js – backbone dependency
- ICanHaz.min.js – for templating
If you don’t have jQuery or Zepto installed, you’ll need one of those too.
Also create a file called `contrib/js/passwords.js` – this is where we’ll actually create our backbone application. Add all of these to your template:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <!-- backbone --> <script type="text/javascript" src="{{ STATIC_URL }}contrib/backbone/ICanHaz.min.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}contrib/backbone/json2.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}contrib/backbone/underscore-min.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}contrib/backbone/backbone-min.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}/js/passwords.js"></script>
Now we’re ready to start building the backbone part of the application. My goal for this stage is just to get something up and running where it’s pulling data in via the API.
Open http://localhost:8000/passwords/ to view what we’ve currently got – data loaded via Django. We want to recreate this, but loading data using backbone.
Add the following to `contrib/js/passwords.js`:
// load the following using JQuery's document ready function $(function(){ // Password model var Password = Backbone.Model.extend({}); // set up the view for a password var PasswordView = Backbone.View.extend({ render: function () { // template with ICanHaz.js (ich) this.el = ich.passwordRowTpl(this.model.toJSON()); return this; } }); // define the collection of passwords var PasswordCollection = Backbone.Collection.extend({ model: Password, url: '/api/1.0/passwords/' }); // main app var AppView = Backbone.View.extend({ tagName: 'tbody', initialize: function() { // instantiate a password collection this.passwords = new PasswordCollection(); this.passwords.bind('all', this.render, this); this.passwords.fetch(); }, render: function () { // template with ICanHaz.js (ich) this.passwords.each(function (password) { $(this.el).append(new PasswordView({model: password}).render().el); }, this); return this; } }); var app = new AppView(); $('#app').append(app.render().el); });
There’s not much to it. Backbone.js represents models as key-value objects to which you can add methods. We don’t need anything fancy at this stage, so we just extend the default class. Collections contain the logic for interacting with an endpoint via REST which we’ve already set up. We’ve also created a view that can render individual password objects, and one that renders the collection by delegating to the password object view.
One point worth noting in the above code is that there are no selectors in the backbone classes. This makes them reusable and more robust. The only line that contains a reference to a selector is the very last line which appends the output of the rendering of the whole application to a specific element.
The last thing to do is to create some templates. We’re using ICanHaz which includes Mustache. Update `templates/passwords/password_list.html` so it contains the following:
{% extends "base.html" %} {% block content %} <h1 class="page-header">Passwords</h1> <table class="table table-striped" id="app"> <thead> <tr> <th>Title</th> <th>User name</th> <th>Password</th> <th>Notes</th> </tr> </thead> </table> {% load verbatim %} <!-- ICanHaz templates --> {% comment %} Mustache and django both use {{}} tags for templates, so we need to use a custom template tag to output the mustache template exactly as it is. {% endcomment %} {% verbatim %} <script id="passwordRowTpl" type="text/html"> <tr> <td> <a href="{{ url }}" target="_blank"> {{ title }} </a> </td> <td>{{ username }}</td> <td class="password">{{ password }}</td> <td>{{ notes }}</td> </tr> </script> {% endverbatim %} {% endblock %}
Save everything and reload the page and you should see your page loading as before. If you’ve got firebug installed, open it, switch to the Net tab and reload the page to make sure that the data is being loaded remotely.
Summary
Now we’ve got a read-only application using backbone and Django, it’s time to move on and add CRUD support to the app.
I think this step won’t work without a “parse” function.
http://stackoverflow.com/questions/14207378/backbone-js-collection-fetch-cant-retrieve-items