Django’s D-day

Development, 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

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.

Learning Django by Example(6): Search

Web January 4th, 2008

Search is one of the must-have functionalities in Gelman. Here is an SearchQuerySet based upon MySQL full text search extension. It is really cool and neat, but

  • first, I don’t want to build my application against specific database extension, even though MySQL is universally picked up in the Web application.
  • second, I still prefer more flexible and powerful search syntax other than what MySQL provides
  • Last but not the least, I may still need Lucene or Xapian to index, search the PDF, CHM eBooks

So I home-brew the search using PLY, the Python Lex Yacc toolchain. You could check the code here, most of parser.py is just boilerplate, the interesting part is to build django.db.models.Q:

def p_expression_term(t):
    ‘expression : TERM’
    t[0] = Q(**{‘title__icontains’:t[1]})

The semantics is quite straightforward: AND(the default), OR operations are supported directly from Q; and only field title is searched. We may extend the syntax using author: like Google does later, so stay tune.

Learning Django by Example(5): Software is hard

Web December 26th, 2007

“Software is hard.” reads the quote from Donald Knuth that opens Scott Rosenberg’s Dreaming in Code. Even the development of Gelman is not smooth as I expected.

Think big, but not fancy

Gelman is a hobby project to scratch personal itch, at the same time it acts as the playground to learn django and dojo. Therefore, it is extremely difficult to resist the temptation for some bling-bling but not essential features, which are called “free feature” in the industry. For example, the fancy django-registration plug-in. It will be cool to integrate a ring-and-whistle registration module, but do I really need this module since I am probably the only user/administrator of this web application, why bother to waste effort in registration?

Deodorize the smell

It is quite annoying to work on a bad structured code base with misleading name convention. Eventually, I decided to re-organize the layout of the source code, and moved out from Google Code to Assembla, since the latter provides the Trac support for online source browser and ticket support.

Some other changes include:

  • Rename library as bookshelf
  • Move the core functionality for book/add to file/add
  • Redesign and develop (in progress) the MassAdd functionality for files in server’s incoming

Find a formal way

What make Gelman stands out is his admin interface, 60% of its functionalities are only available to administrator. When working with admin module, we should play the game of default admin. Eventually, I may have to copy the code from admin module for the sake of security and behavior consistency. In this situation, the Django Book cover what is on the table, but not under the table.

Here is just a snapshot of current progress, the MassAdd.
MassAdd