In the last post, we succeeded to post the Javascript objects via JSON to the server, the data is to be serialized to the database in this section.

Before we move on, let’s remove some bumps in our way, the database scheme is modified in this way:

class Book(models.Model):
isbn = models.CharField(maxlength=10, primary_key=True)
pub_date = models.DateField(’data published’)

The reasoning lies in that AWS returns ISBN-10 as ASIN, we may take advantage of this. Another fix is to replace DateTimeField by DateField for pub_date. Django does not support seamless database scheme refactory so far. So we just dropped the database and re-generate it as described in the tutorial. The username/password for new database is set as admin/gelman as common practice.

It is quite annoying that a 500 error returned without any reason, Django server ate the exception due to the nature of Web server. We could wrap the suspicious buggy code with try/except block like this:

try :
    // database access
except :
    print sys.exc_info()[0]

Well, InterfaceError or IntegrityError pinned the bug in database insertion, but where? Interactive shells are our best friends, you can either use pdb or python manage.py shell.

Oh, my fault, I forgot the return value of get_or_create is a tuple, instead of the object; and for many to many relation, we could not simply set a list as its value, we need to use add method after the object is constructed:

for item in simplejson.loads(request.POST[‘items’]):
        publisher, created = Publisher.objects.get_or_create(name=item[‘publisher’])
        authors = [Author.objects.get_or_create(name=au) for au in item[‘authors’]]
        authors = [author for (author, created) in authors];
        y,m,d = [int(x) for x in item[‘pub_date’].split(‘-’)]
        pub_date = date(y, m, d)
        book, created = Book.objects.get_or_create(isbn=item[‘isbn’], name=item[‘title’],
            pages=300, pub_date=pub_date, publisher=publisher)
        book.authors.add(*authors)
        #print sys.exc_info()[0]
    return HttpResponseRedirect(‘/admin/library/book/’)

At the exit, we just redirect the browser to a new URL.

It seems the database is updated, but the page is not redirected. Since the POST operation is launched in an AJAX request, we need to send JSON object as the response. In server side, simplejson.dump is used:

xhr = {’succeed’: [], ‘failed’: []};
       for item in simplejson.loads(request.POST[‘items’]):
               # … ….
               try :
                       book, created = Book.objects.get_or_create(isbn=item[‘isbn’], name=item[‘title’],
                               pages=300, pub_date=pub_date, publisher=publisher)
                       book.authors.add(*authors)
               except :
                       xhr[‘failed’].append(item[‘title’])
               xhr[’succeed’].append(item[‘title’])

       return HttpResponse(simplejson.dumps(xhr), mimetype=‘text/javascript’);

In client side, we evaluate the JSON string then populate the DOM nodes:

dojo.xhrPost({
                url: dojo.byId(“book_form”).action,
                content: { items: dojo.toJson(formdata) },
            }).addCallback(function(response) {
                var result = dojo.fromJson(response);
                var messages = dojo.query(“ul[@class=messagelist]“)[0]
                dojo.forEach(result.failed, function(item) {
                    var msg = document.createElement(“li”);
                    msg.innerHTML = “<li><em>” + item + “</em> <strong>failed</strong> to add.</li>”
                    messages.appendChild(msg);
                });
                dojo.forEach(result.succeed, function(item) {
                    var msg = document.createElement(“li”);
                    msg.innerHTML = “<em>” + item + “</em> successfully added.”
                    messages.appendChild(msg);
                });
            });

The final result looks like this:

Add books with feedback



Check r19 for details.


6 Comments to “Learning Django by Example(3): Just works”

  1. Observer | September 8th, 2007 at 10:34 am

    “It really bugged me for the unexpected 500 error, and Django server ate the exception due to the nature of Web server.”

    Wouldn’t setting “debug = True” in the settings.py file fix that?

  2. Learning Django by Example(4): First user authenticated by Refactor the Life | September 18th, 2007 at 7:03 am

    [...] Django by Example(4): First user authenticated Posted on September 18th, 2007 in Web In the last post, we succeeded to update the database, in this section, we would refine the view of normal [...]

  3. Todd | September 19th, 2007 at 12:10 pm

    This was a hard tutorial to follow but I did find it very helpful. I wouldn’t have completed it without the code in subversion.

    I had a few problems getting this to work on Windows XP. Python on Windows doesn’t like a comma after the last item in a dictionary. I had to edit templates/admin/library/book/add.html in 3 places (removing the comma before the closing brace ‘}’.

    The respose coming back has to be edited too for the same reason. I used fiddler tool to catch the response and edit it before releasing back to the browser. Just remove all commas before the closing brace ‘}’. I assume the stylesheet could be modifed to do this.

    I plan to try this at home on Ubuntu to see if Python handles the code as-is. I’d like to code to be platform independent.

    Thanks for the tutorial. I want to use amazon services to search for music, pull album covers and display them. This is a great place to start.

    Windows XP / Python 2.5.1 / MySql 5.0

  4. Learning Django by Example(5): Time to Attack by Refactor the Life | September 19th, 2007 at 2:24 pm

    [...] 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 [...]

  5. tomcask | February 11th, 2008 at 1:38 pm

    Another translate!!!

    http://tomascasquero.com/desarrolloweb/pami-aprendiendo-django-con-ejemplos3-trabajando/

  6. Getting Started With… | Resource Pile | July 17th, 2008 at 6:28 am

    [...] Monkey’s Getting Started with Django Kunxi.org’s Learning Django by Example(Part 1, 2, 3, 4, 5, 6, 7, [...]

Leave a Comment