Restart the Django engine

Python, Web January 10th, 2009

It has been one year since the last update of my Learning Django by Example series, partially in account of the demanding day job, the main reason lies in that the project is bloated with some advanced features which delay scratching my itch. Thanks to the snow storm in the holiday season, our vacation to Las Vegas was canceled, I had time to restart the Django engine.

The new project, Pattee, named after the library in Penn State University, aims to a simple, stupid eBook management system. It is so simple that it even does not have a dedicated UI, only integrated to a third-party web application(currently, douban.com). You may check it out at here:

svn checkout http://my-svn.assembla.com/svn/pattee/trunk pattee

There is no step-by-step tutorial to follow the footprints of the Django Book, each post will target a specific topic.

I may post

Reverse mashup

Web September 3rd, 2008

I barely remember when was the last time I updated Gelman. This project starts as an exercise to practice my Django + dojo skills, and also to manage my eBook collection, I were stuck in UI design which I suck and the authentication/registration which I takes little interest in.

What if we take a different approach to avoid the reinvention of the wheel? Let’s take an online eBook management Web2.0 application, for example LibraryThing, to manage the Read, Reading, Wish to Read list, if an electronic copy is available, it will be inserted into the LibraryThing search/detail page, and we can add it to Reading list for quick access later. We just mashup our web service into LibraryThing!

This application can be decomposed to two parts:

  • A Web service to CRUD eBook collection hosted in home-brew server
  • Firefox Add-on or GreaseMonkey user script for mashup
  • A web service client to automate importing books
  • Find your favorite app, then mash it up!

A more portable solution to glue the pieces is to leave the mashup in the server side, using a proxy server to insert all the mashup data.

As all comments, tags, reading history has been hosted in the cloud, it is essential to do something against the raining day:

  • Big name may endorse the availability. I would seriously consider Shelfari only after it is acquired by Amazon
  • Open API is the key. This is the trend, the web site could not lock on the user by closing itself, the users may cold feet in the first place. Douban, the leader in the Chinese market, did an excellent job to open its platform.

I am working on an prototype of the RESTful web service using Django, stay in tune.

Django’s D-day

Development, Python, Web April 7th, 2008

Google just released the Google App Engine in python development environment. The environment is loaded with WSGI, and Django 0.96 “for convenience”.

Just checked the Datastore API, it is a copycat of Django reference. Google’s engineers hacked the Django’s Model to support Google’s datastore, aka BigTable. Bang! Google Account is also supported via User API, no idea whether it is integrated to Django’s authentication framework though.

I am so glad that Google has made such a move, I can bet the Django users may grow exponentially in the following couple months. Today is Django’s D-day.

HOWTO deploy Django in Jumpline

Web February 24th, 2008

The blogosphere discussed the headache of deployment for modern Web Framework on shared hosting recently in couple weeks ago. This HOWTO documents the bumps and workaround in deploying Django to Jumpline’s VDS(Virtual Dedicated Servers) hosting.

Compared with the ironclad shared hosting, VDS provides SSH access, and private Apache server. Jumpline’s plan is also shipped with mod_python(python 2.5) and write access to PYTHON/site-package and /usr/local/bin, that make the whole process less painful.

Setup the VirtualHost

Add a sub-domain as planet.kunxi.org in VDS console as our testbed.

Install Django SVN

It is a pity that Subversion is not installed in the chroot jail. In fact the Subversion hosting is a premium feature you need to pay for. Anyway, we can just check out the code in the local machine, then copy it back to the server. In the server:

python setup.py build
python setup.py install –prefix=/home/lib

If you happen not to have write privilege PYTHON/site-package, you may consider add –prefix to override the default installation path, then add the prefix to your PYTHONPATH environment variable.

Setup the mod_python

Load mod_python in httpd.conf

LoadModule python_module modules/mod_python.so

As the name suggests, planet.kunxi.org is a feed aggregation portal based upon FeedJack, some enhancement are in plan to scratch the etch, now it is just mere a simple deployment:

<VirtualHost *:80>
    ServerName planet.kunxi.org
    DocumentRoot /var/www/planet
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    PythonDebug On
    PythonPath "['/home/projects'] + sys.path"
    SetEnv DJANGO_SETTINGS_MODULE feedpipe.settings
    <Location "/media">
        SetHandler None
    </Location>
    <Location "/static">
        SetHandler None
    </Location>
</VirtualHost>

/media and /static are set to host static media contents. /media is mere a soft symbol link to django/contrib/admin/media. We also link /static/feedjack to feedjack’s media files as FeedJack’s document suggests. Here is the feedpipe.settings:

MEDIA_ROOT = ‘/var/www/planet/static’
MEDIA_URL = ‘/static/’
ADMIN_MEDIA_PREFIX = ‘/media/’

Restart httpd, done.

Learning Django by Example(7) Attach a tag

Python, Web January 20th, 2008

Tag is probably the most distinguish feature of Web 2.0 applications that differentiate them from the traditional hierarchy categories. I want to attach a Web 2.0 tag to Gelman, so the user could simply click the tag, and find the related books that may arouse his/her interest.

django-taggingis a generic tag application to simplify the backend development, all you need to do is just add the TagField to the Book model:
class Book(models.Model):
……
tags = TagField()

And in the book_detail.html template, refer it as object.tags as this:

{{ object.tags|popuptags|safe }}

popuptags is a custom tag that decorates the tags as a list of HTML links, and join them:

@register.filter
def popuptags(value):
    tags = value.split(" ")
    return " ".join(['<a href="/bookshelf/tags/%s">%s</a>' % (x, x) for x in tags])

So tag foo is linked with /bookshelf/tags/foo, so just redirect the request to the view:

(r'^tags/(?P<tag_name>[\w-]+)/$', views.by_tag)

And handle it in views.py:

@login_required
def by_tag(request, tag_name):
    tag = Tag.objects.get(name=tag_name)
    return list_detail.object_list(
        request,
        queryset=TaggedItem.objects.get_by_model(Book, tag),
        template_name="bookshelf/book_list.html",
        extra_context={'title': 'Tagged by %s' % tag_name},
    )

All the tedious work has been handled by django-tagging: we first get a tag object by name, and then build a QuerySet using get_by_model method; the rest is handled by the generic view, done. Salute to django-tagging developers!

We would discuss how to add a tag in the next post, that is the magic of Dojo.