12.12.08

django’s O/R mapper, list comprehensions and lambda functions

Posted in python at 11:35 am by karl

I have been using django of late and am very impressed with most of it. Here’s just 1 little gem. Suppose you have 3 models like this:

class Owner:
    name = models.CharField("name", max_length=100)

class Pet:
    name = models.CharField("name", max_length=100)
    owner = models.ForeignKey(Owner, verbose_name=_(u"owner"))

class Toy:
    name = models.CharField("name", max_length=100)
    owner = models.ForeignKey(Pet, verbose_name=_(u"owner"))

This represents pet owners, each of whom may have zero or more pets. Each pet in turn may have zero or more toys. So far, so simple. Now suppose we want the owner to have a property saying how many toys in total she owns (the pets don’t really own the toys!). There are a whole bunch of ways to do this, but one neat way python/django makes possible is to change the definition of Owner to this:

class Owner:
    name = models.CharField("name", max_length=100)
    toy_count = property(fget=lambda self:sum([pet.toy_set.count() for pet in self.pet_set.all()]))

There are a couple of things going on here: properties, lambdas, list comprehensions and many-to-one relationships as expressed by django’s O/R mapper. Together they allow for some concise yet powerful constructs like the one above.

Leave a Comment

You must be logged in to post a comment.