Updates to django-dbtemplates and a half-assed promise

Given my long abstinence from this very weblog I would like to take the opportunity to post some stuff I’ve been doing the last couple of months. That’s especially easy since I have some people to stay on the wheel with (Brian Rosner, James Tauber, Justin Lilly, Greg Newman, Eric Holscher and Eric Florenzano) — all pals from the wider Django community, most of them also connected to the project I’ve been spending my nights with in the last six months: Pinax. They are all doing the one-post-a-day marathon in November. Maby I do, too.

dbtemplates 0.5.0

This time I want to talk a bit about some changes I recently did to a small reusable Django app of mine, that provides an easy way to save Django templates in the database, instead on the file system.

With the release of django-dbtemplates 0.5 it includes changes, mostly inspired by a short conversation with Alexander Artemenko on Github in which he proposed to add the ability to load the contents of a new database template from disk if the content field is left empty. That speeds up the process of moving filesystem templates a bit because users don’t need to copy and paste every thing if the templates are in reach of other template loaders anyway.

version control

We also talked about adding version control to dbtemplates to enable users to jump back and forth in case a change to a database template didn’t work out so well. We first considered a project of Arne Brodowski: django-rcsfield, which is a pretty nifty piece of software that uses “real” version control systems to versionize database field contents, while always keeping the HEAD version in the database. Although I trust the Git backend I wrote for it to handle different versions of the database templates, we figured it would be not too useful for end users like editors and authors who for various reasons don’t have access to the filesystem of the server.

So I actually ended up adding support for django-reversion, a third party app that saves different versions of a database entry in a other table, everytime Django’s post_save signal is fired. Very useful and during my tests also very stable. dbtemplates supports it out of the box — once django-reversion is installed properly, it will versionize every change of your database templates — accessible in the usually unchallenged “history” section of each database template.

caching backends

The third big change is the addition of a customizable caching backend. Until now you were only able to let dbtemplates cache every database template on the file system to speed things up and reduce the number of database queries.

I replaced that mechanism with a pluggable backend system to allow other ways of handling template loading and provide a simple API to build your own.

dbtemplates comes with two backends by default: FileSystemBackend, which is a port of the old way of doing things and DjangoCacheBackend, which is a thin wrapper around Django’s insanely useful caching framework. Be sure to checkout dbtemplates’ documentation to learn more about it.

Writing an own backend is as easy as pie:

from dbtemplates.cache import BaseCacheBackend
class AwesomeBackend(BaseCacheBackend):
    def load(self, name):
        """Loads a template from the cache with the given name"""
        return 'I wanted this template: %s' % name

    def save(self, name, content):
        """Saves the given template content with the given name.""" 
        print 'Saving the template %s with the content %s.' % (name, content)    

    def remove(self, name):
        """Removes the template with the given name from the cache."""
        print 'Bye bye, %s' % name

That’s it. Put that code somewhere in your code base and point dbtemplates to it by specifying the DBTEMPLATES_CACHE_BACKEND setting, e.g. 'awesome_app.cache.AwesomeBackend'.

Feel free to hop on IRC to #django-hotclub or visit code.google.com/p/django-dbtemplates/ to learn more.

Django, Python Nov. 1, 2008, 11:50 p.m. comments (36)

newcomments are in trunk

Just a short message concerning the Google Summer of Code.

I’m proud to report that the Google Summer of Code student Thejaswi Puthraya that I had the privilege to mentor this year, not only finished his task successfully but also did that in time for Django 1.0!

Changeset 8557 has all the interesting details, so hop over to the new and shiny comments documentation and enjoy. Huge thanks to Jacob for his groundwork and the documentation work.

Django Aug. 26, 2008, 10:58 a.m. comments (18)

Easy overrides for absolute URLs of reusable apps

Welcome to the new jannisleidel.com, after finally being migrated from Wordpress to Django. I’m now a happy user of James Bennett’s Coltrane app. It provides the features I used in the old Wordpress installation and is simple enough to be hacked in the spare time. One thing though was new to me and I want to share this little piece of usefulness with you.

By default Coltrane uses a URL scheme for the weblog entries like:

r'^(?P<year>\d{4})/(?P<month>\w{3})/(?P<day>\d{2})/(?P<slug>[-\w]+)/$'

If you want to change that URL scheme without modifying Coltrane you can fairly easily override the provided URLconf with your own. For example I’m using the following regular expression here:

r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)/$'

But this is only half the battle. Furtunately, Coltrane uses absolute URLs for the entry models. And this is when a special setting needs to be brought into play: ABSOLUTE_URL_OVERRIDES — “A dictionary mapping “app_label.model_name” strings to functions that take a model object and return its URL.”

Combined with the reverse() utility it’s a nice, small solution, you can put in the settings.py file of your site:

from django.core.urlresolvers import reverse
ABSOLUTE_URL_OVERRIDES = {
    'coltrane.entry': lambda o: reverse('coltrane_entry_detail', kwargs={
                                            'year': o.pub_date.strftime('%Y'),
                                            'month': o.pub_date.strftime('%m'),
                                            'slug': o.slug }),
}

Django Aug. 21, 2008, 4:03 p.m. comments (4)

1 2 3 4 58 9 10 11