Learning Django by Example(1): Start the Engine
Python, Web September 3rd, 2007
This is yet another Django tutorial, it makes a difference since
- the author is totally a noob about Django programming, he has little experience on database and Web framework. You may find it interesting how a newbie benefit from the elegant design of Django.
- each step is carefully recored via Google Code, you can check out the snapshot to understand how the project evolves.
Translations are freely permitted as long as they are released under Attribution-Noncommercial-Share Alike Creative Common License. Learning Django by Example has already been fully or partially translated into several languages. If you translate it into another language and would like to be listed here, just let me know.
- Spanish, thanks to Tomcask
Think Big
I really love the intuitive interface of Delicious Library, unfortunately, it is Mac-only, and it may not scale due to the lack of database server support. Personally I prefer a small daemon running silently in my old Gentoo box to serve contents to all clients, cross-platform and it is supposed to scale when the library grows, and I may share the resources with my friends. So I decide to brew my tea: Gelman, named after the library in the main campus of the George Washington University.
I choose Django for the python on rail hype. I just need a lightweight, pythonic Web framework. Hopefully I could enjoy the development process.
NOTE: In the following tutorial, I would show the code snapshot in each step, when I mention check r#, you can checkout the code via:
in the case, # is 3. If Google code supported Trac, that make it much easier.
Start the Engine
Installation of django-0.96 in Gentoo is like a breeze, just emerge it. And follow the official tutorial to initialize the project and setup the database, sqlite3 is used in the rest of tutorial for the sake of simplicity. When it is in production use, we would migrate it to MySQL . Check r5.
Next, add an application library:
Gelman is designed as a lightweight eBook management system, so it make senses to reuse existed components and Web services. For example, the meta data is from Amazon Web Service(aka AWS), the tag suggestion may come from Yahoo. Only the essential information is stored locally, such as the mapping between the meta data and eBook. The following models, Author, Publisher and Book are added.
isbn13 = models.CharField(maxlength=13, primary_key=True)
name = models.CharField(maxlength=255)
authors = models.ManyToManyField(Author)
pages = models.IntegerField()
publisher = models.ForeignKey(Publisher)
pub_date = models.DateTimeField(‘data published’)
ISBN-13 is the latest standard, we may add ISBN-10 later if necessary. Author and Book is many to many related, so use models.ManyToManyField as suggested. Finish the following boilerplate work to make it run:
- Add django.contrib.admin to INSTALLED_APPS setting
- Sync the change to the database
- Edit the urls.py to enable the admin page
Now we can login to http://localhost:8000/admin using bookstack and gelman as the Username and Password, check r7.
Initially, books are added manually for a test drive, we would automate this tedious procedure later. Notice the link between the Book and Publisher, it is really cool that the admin would help us to handle the relation of models.

Add one line to the urls.py to enable the user interface for normal users:
Add the detail.html in template/books as the view template, don’t forget to set TEMPLATE_DIRS variable in settings.py, then implement detail in library/views.py:
book = get_object_or_404(Book, isbn13=isbn)
return render_to_response(‘books/detail.html’, {‘book’: book})
Now we can access the data via: http://localhost:8000/library/9780596009250/, it is just a boring raw text, we would refine it later. Check r8.
Make Librarian happier
In a real library, the user may browser, search, borrow, return books, but only librarian manage the collection. It is less fun to type all the meta data of the book while we can fetch it from Amazon. As a librarian instead of bar code reader, I prefer title/keyword than boring 13 digital numbers.
And AJAX of course, who is not using it? I will eat my own dog food, The Dojo Javascript Toolkit. You can either use dojo-0.9 release to take full advantage of AOL’s CDN(thanks, Alex) or the SVN version just as I did.
how to server the static file is probably the most frequently asked question in #django since the regular expression based URLConf more or less overkill, :-)
And prepare the files as well:
mkdir scripts
sudo mount -o bind $DOJO_ROOT/trunk scripts
Now http://localhost:8000/static/scripts/dojo/dojo.js would point to the dojo.js ultimately.
Consider users may input dash and space in ISBN, we need to override the default maxlength attribute of Isbn13 and add a validation for ISBN using JavaScript:
var p = dojo.byId("id_isbn13");
var n = document.createElement("div")
p.parentNode.appendChild(n);
dojo.connect(p, ‘onblur’, function() {
if(isValidISBN(p.value)) {
n.innerHTML = "<div>Searching…</div>"
} else {
n.innerHTML = "<div>Invalid ISBN</div>"
}
});
p.removeAttribute("maxlength");
});
NOTE: isValidISBN is merged into dojox.validatie.isbn, renamed as dojox.validate.isValidIsbn. That is just one of benefits to run dojo SVN.
It is a good chance to customize the admin page, a new template add.html is added:
<div id="content-main">
<h1>Add Book<h1>
<input type="text" id="id_isbn13" class="vTextField" name="isbn13" size="30" value=""/>
<input type="button" id="search_isbn" value="Search ISBN" />
<div id="isbn_valid"></div>
<input type="text" id="id_title" class="vTextField" name="title" size="30" value=""/>
<input type="button" id="search_title" value="Search Title"/>
<form action="" method="post" id="book_form"> <div>
<fieldset class="module aligned ()" id="books">
<div class="form-row" id="firstrow"> No book found
</div>
</fieldset>
<div class="submit-row">
<input type="submit" value="Save and add another" name="_addanother" />
<input type="submit" value="Save and continue editing" name="_continue" />
<input type="submit" value="Save" class="default" />
</div>
</div></form>
</div>
{% endblock %}
If we use XMLHttpRequest, we have to go through the boring XML parsing and deploy a proxy to bypass cross-domain AJAX. Neither of them is pleasant. AWS’s JSONP interface is the rescue. In dojo 0.9, dojo.io.script.get replaces the magic dojo.io.bind with Twisted-like syntax, that make it even sweeter.
dojo.io.script.get({
url: ‘http://xml-us.amznxslt.com/onca/xml’,
content: {
Service: ‘AWSECommerceService’,
SubscriptionId: ’19267494ZR5A8E2CGPR2′,
AssociateTag: ‘kokogiak7-20′,
Operation: ‘ItemLookup’,
Style: ‘http://kokogiak.com/amazon/JSON/ajsonSingleAsin.xsl’,
ContentType: ‘text/javascript’,
IdType: ‘ISBN’,
ResponseGroup: ‘Medium’,
SearchIndex: ‘Books’,
ItemId: isbn.value,
},
callbackParamName: "CallBack"
}).addCallback(function(response) {
var item = response.Item;
var row = dojo.byId("firstrow");
row.textContent = null;
var node = document.createElement("div");
node.innerHTML = ‘<div> <img src="’ + item.thumburl + ‘"/> ‘ + item.title;
row.appendChild(node);
});
});
NOTE: All the parameters are case-sensitive, especially CallBack for callbackParamName. Check r10. Oops, I forgot add it to the repository, so please check r11 for the updated version, further explanation is in section 2.
The above code is dojoized Kokogiak’s idea, and we still use his ajsonSingleAsin.xsl for quick prototype, we would develop a XSLT to meet our requirement in the next section.








I couldn’t understand some parts of this article ning Django by Example(1): Start the Engine by Refactor the Life, but I guess I just need to check some more resources regarding this, because it sounds interesting.
[...] Learning Django by Example(2): Show me your data Posted on September 5th, 2007 in Web In last post, we wrapped up the different pieces and make Gelman running, we would continue keep working on the [...]
[...] out perusing bookmarks and randomly following links, I stumbled across a nice “from the beginning” Django tutorial that includes a little bit of Ajax with the Dojo Toolkit. There’s also a Part 2 to the [...]
[...] Learning Django by Example(1): Start the Engine [...]
Hey Kun,
This series rocks.
As a quick aside, you can use a .forEach() method directly on the result of a dojo.query() call. Also, users can now use Dojo 0.9 out of AOL’s CDN so they don’t need to download anything. The details are at http://build.dojotoolkit.org/0.9.0/
Again, great stuff.
Regards
[...] Learning Django by Example(1): Start the Engine by Refactor the Life I really love the intuitive interface of Delicious Library, unfortunately, it is Mac-only, and it may not scale due to the lack of database server support. It is preferred to run a daemon silently in my Gentoo box and serving various clients, portable and (tags: ajax django dojo javascript json tutorial ebooks application) [...]
[...] by Example(5): Time to Attack Posted on September 19th, 2007 in Gentoo In the last four section(1, 2, 3, 4) ,we have been familiar with the environment, it is time to do some real [...]
[...] Learning Django by Example Using Jjango to make a Delicious Library web clone. (tags: ajax javascript learning python webdev books library) [...]
thanks for the GREAT post! Very useful…
in advance, sorry for my english.
Congratulations on the article.
I have a free Spanish translation of this article in my blog (http://tomascasquero.com/desarrolloweb/aprendiendo-django-con-ejemplos-1-arrancando/), if not to your liking, I hope your notice to remove it.
Thanks.
Thanks for your notice and following the same license. Yes, I hope this serial may benefit more people whose native language is not English.
Thanks for the link
At the end of page I fetched r11 and tried add_book but all I got was
lineNumber 51
message “searchISBN is not defined”.
name “ReferenceError”
stack “()@http://localhost:8000/admin/library/book/add/:51\n()@http://localhost:8000/static/scripts/dojo/_base/_loader/loader.js:146\n()@http://localhost:8000/static/scripts/dojo/_base/_loader/loader.js:235\n()@http://localhost:8000/static/scripts/dojo/_base/_loader/loader.js:218\n([object Event])@http://localhost:8000/static/scripts/dojo/_base/_loader/hostenv_browser.js:233\n@:0\n”
@hollerith,
I also checked r11, and found in r11, the Search ISBN and Search Title already merged. So could you please double check whether you checked out the correct revision?
Some other things may help:
In settings.py, the template path is hard-coded. This design flaw has been fixed later when I migrated the repository from Google Code to Assembla.
Also the dojo SVN may be replaced by the dojo AOL CDN. That may save some trouble for you as well.
I must confess I am quite lousy when handling the code revision, it is so often that some file are forgotten to checkin. If this version does not work, please try the next revision, reading the SVN log and diffing between revisions may help as well. Really sorry about the inconvenience.
[...] Web Monkey’s Getting Started with Django Kunxi.org’s Learning Django by Example(Part 1, 2, 3, 4, 5, 6, 7, [...]
I do not believe this
[...] 5. Learning Django by Example [...]
[...] the Tutorial on the Djangoproject page and the Djangobook I found “Learning Django by Example” but I am sure there are others out [...]
This is a nice piece of code. Can I bookmark this and then mention it on my blog?
This is a nice piece of code
Learning Django by Example is Mac-only, and it may not scale due to the lack of database server support.
Thanks for this tutorial. I just followed it as a new Python and Django developer and found it very comprehensive.
[...] 5. Learning Django by Example [...]
Sound so interesting..I feel like I also want to learn Django though I don’t have any experience on data base and web framework..But I guess its worth the try..