Learning Django by Example(5): Time to Attack


In the last four section(1, 2, 3, 4), we do some warm up to get familiar with the environment, it is time to do some real work.

I will add more fresh to models.py, linking eBook file and its meta data, thumbnail of the cover, regular size cover etc. Two other models are added for eBook:

class FileType(models.Model):
    type = models.CharField(maxlength=10)

class File(models.Model):
    type = models.ForeignKey(FileType)
    handle = models.FileField(upload_to="files")
    meta = models.ForeignKey(Book)

Book to File is one-to-many as one book may have more than one formats, a PDF version for print, a CHM version for reference.

To server the images of book covers, , we need to setup the MEDIA_ROOT and MEDIA_URL:

MEDIA_ROOT = '/home/share/eBooks/'
MEDIA_URL = 'http://localhost:8000/repo/'

and setup the url mapping as well:

(r'^repo/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/home/share/eBooks'}),

To save an image file, we can easily call save_FOO_file method, it works with two drawbacks: first, you need to read the image into the memory; second, it is synchronous function call aka it is blocked until the file is fetched, read and written. urlretrive is preferred in this way:

from django.conf import settings
from urllib import urlopen, unquote, urlretrieve
from urlparse import urlparse
from os import path
... ...

thumb = unquote(urlparse(item['thumburl'])[2].split('/')[-1])
# using hard-coded image temporary
urlretrieve(item['thumburl'], path.join(settings.MEDIA_ROOT, 'images', thumb))
book.thumb = path.join('images', thumb);

A further optimization may introduce Twisted or asyncore.

More work needs to be done in the UI side: the Book objects are populated in brief or detail modes. Brief mode just highlight the title, cover, authors and ISBN of the book, commonly used in general listing, search results, my favorite and so on; while detail mode shows more detailed information like editorial review, related book, tags etc. It is worthy extracting the code snippet of brief mode to a template, so we can reuse it later by {% include book_item_brief.html %}. Detail view would fetch the editorial view from Amazon using the same AJAX hack as discussed before.

With stylesheet, it looks much better, Brief view:

Breif view
Breif view

and Detail view:

Detail view
Detail view

Check r30.