Eric Florenzano's Latest Posts and Links for Tag Django

Feed Items

First Two Django Screencasts

It's always been a goal of mine to post screencasts here on my blog, but for whatever reason I never ended up getting around to it. Today, that all changes as I have created two new screencasts. Of course, this space is already very well-covered by both Michael Trier and Brian Rosner, so hopefully this adds something new to the conversation.

Setting up a Django Development Environment

In this screencast I show how I typically set up my Django development environment. It goes through installing Django by checking out the latest development version and linking it to the correct places on your system. It also talks about how to install reusable applications. Finally, it covers how to update all of those projects and keep a toolbox of snippets for your personal use.

The simple pylink command that I use in the screencast is this:

#!/bin/bash
ln -s `pwd`/$1 `python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"`/$1

Please let me know in the comments if you have any other tips and tricks for setting up a development environment for Django.

Using Django-Pagination

Django-pagination is an application that I wrote and released a while ago, which I use all the time, but that hasn't really seen much attention. In this screencast, I show how to take an existing project with too much data on one page, and use django-pagination to quickly and easily paginate the items on the page. There is a bit more documentation for the project that's available in the project directory if you do a subversion checkout, and docstrings throughout the source code, if you're interested in how it works.

Keep in Mind

These are my very first screencasts, ever. I'm not entirely sure what I'm doing yet, and the only way I can improve is by your feedback. If you have any advice and/or criticisms of these screencasts, please don't keep your mouth shut--speak up, and let me know in the comments. Hopefully someone finds these useful, and thanks for watching!

[Link] How I Work Daily

Daily blog by Kevin Fricovsky. In addition to having some really great content, he has started to post audio interviews with people from the Django community. This is a site to keep an eye on in the coming days and months.

[Link] django-arcade

Demo site for django-arcade, an open source reusable Django app to add new flash games to any django-powered site. Looks very cool for easily creating game portals. It also comes from my future employer.

Djangodash was Fun!

Djangodash, a two-day two-person sprint to create a project using Django, took place last weekend. To be honest, I wasn't expecting it to be much fun, but it ended up being an absolute blast!

Feedalizer.net

Before getting too far into this post mortem, I'm going to just get it out of the way and shamelessly promote the site that Tony and I created during the dash: feedalizer.net. The idea behind the site is that it's a feed aggregator, but people vote on the feeds. The higher the feed's score, the more likely items from that feed will bubble up to the top of the list. There's also the concept of a "channel", which only aggregates feeds for a specific area. For example, there's a Humor channel, a Django channel, and a Python channel. You can also subscribe to channels to create your own "station", which aggregates the content from the channels that you care about.

The idea came to me when a friend of mine asked me "I've never used a feed reader before, but I want to get started and subscribe to programming feeds. What are some good ones for me to subscribe to?" It took me about 30 minutes to cull through my feeds and produce a list of the best. But it shouldn't have taken me any time at all--there should have been a site out there to do this for him!

OK, enough shameless self-promotion.

The Dash

52 teams registered for the dash, so watching the commit activity at the turn of the clock was pretty crazy. Unfortunately, Tony was driving from 4 hours away and he hadn't arrived yet. When he did arrive, we both wanted to spend some time catching up and talking about non-Django things. So we didn't even get started until about 3:30AM. Getting started mainly consisted of frantically checking in 3rd party projects that we thought we would use, and talking about architecture, and writing a few cron jobs. Not much code got written that night (morning?), since we still had a lot of planning to do.

The next day, all of a sudden our commits weren't working! We went to the website to see what was going on, and the website wasn't responding to our requests. Something was definitely going on, and it was slowing down our progress significantly. We tried working on our own separate parts of the project, but at this early stage there was simply too much overlap. We found out later in the night that there were problems at Webfaction's data warehouse,`The Planet`_, where a transformer quite literally exploded.

This severely slowed us down, because we ended up having to switch to git, and then once we got everything into our git repository, we had tons of merge conflicts. We got an e-mail saying that the due date would be postponed, so we decided to take the afternoon and night off to do other things.

The next day we did the brunt of our work. I had the task of designing the frontend, so I opened up my trusty text editor and hammered out the worst-looking CSS file you'll ever see in your life, producing some of the worst-looking pages you'll ever see in your life. This changed over the course of the day, but not by much as you'll see if you visit the site. This same day, Tony was working on some of the harder queries etc.

The final day (the deadline had been extended, remember) was all about integration. There was nothing really notable about this, but it took all day to get everything working properly together. I ended up writing a bunch of Javascript to make the client experience more enjoyable, and Tony had the chance to debug his views now that I had templates and we had sample data. It was a crunch to make the deadline, but we tried to do the little important extra details like write an "about" page, a README file, etc.

Conclusion

Whether we win or lose, and despite the technical difficulties that The Planet suffered, I had a blast doing the competition. I think that our idea is novel, and Tony and I got to work on something once more post-graduation. (Nothing like a programming competition to bring people together, I always say.) In fact, we'll probably continue to work on it for the months to come, especially in upgrading its graphics. It's going to be really awesome to see what everyone else produced this year. I encourage anyone who thought about participating this year, or anyone who even considers it as a possibility, to sign up and just do it next year!

Managers and Voting and Subqueries, Oh My!

Recently I launched Peevalizer, a website for talking about your pet peeves, which of course was written in Python using the Django web framework. In fact, it was the culmination of my efforts to teach myself design, and while I made some progress, it's clear that I'll never be a designer. Anyway, part of Peevalizer is that users can vote on different pet peeves, and view the peeves with the highest score. I used django-voting as the application to enable this functionality, and it provides a manager on the Vote object with methods for getting the top N results, where N is a positive integer.

One of the reasons for custom manager on Vote is because aggregate support has not yet been finished. However with Django's built-in Pagination support, it's necessary to retrieve not only a list of the top N voted pet peeves, but a list of all of the pet peeves, ordered by score. How is this possible? Specifically, how is this possible without forking django-voting? Here is the solution that I came up with:

class VoteAwareManager(models.Manager):
    def _get_score_annotation(self):
        model_type = ContentType.objects.get_for_model(self.model)
        table_name = self.model._meta.db_table
        return self.extra(select={
            'score': 'SELECT COALESCE(SUM(vote),0) FROM %s WHERE content_type_id=%d AND object_id=%s.id' %
                (Vote._meta.db_table, int(model_type.id), table_name)}
        )

    def most_hated(self):
        return self._get_score_annotation().order_by('-score')

    def most_loved(self):
        return self._get_score_annotation().order_by('score')

Then I assigned that manager onto all of the objects that could be voted on. What that's doing is literally issuing a subquery for every row, doing an aggregate on all of the votes for that row, and assigning it to an attribute named score.

However, we also wanted to allow for voting on User objects, which is built in to Django and cannot be easily changed. How do we add this manager to user? I spent a while thinking about that before realizing that it's not the right question to ask. The right question to ask is, how can we associate the User model with this manager? A quick look through some Django source code revealed this to be an absolutely trivial task. Here's how it goes in our code:

from django.contrib.auth.models import User
manager = VoteAwareManager()
manager.model = User

for user in manager.most_hated():
    # Do something with user's score

There are a few things to note about this implementation. Firstly, it can be much more computationally expensive to use this method instead of using django-voting's method (which executes some custom SQL), so either be aware of that or use aggressive caching strategies to overcome this shortcoming. The other thing is if you're not using a manager like this on multiple models, and since managers mostly just proxy to QuerySet anyway, it might be simpler to just acquire a QuerySet on the model that you would like to get, and run the extra() method in the calling function.

Exploring Mixins with Django Model Inheritance

Django now supports Model Inheritance, and one of the coolest new opportunities that model inheritance brings is the possibility of the creation of mixins, so in this post I'll walk through the steps I went through to create some simple examples. This is just an excercise (although it could be modified to be more robust)--and right now there are better ways to achieve all of the effects of the following mixins. (See django-mptt, for example).

Model and Field Setup

First let's just set up two basic models. The first will be our mixin, NaiveHierarchy, which has a single field, parent, which is a reference to itself. Using this, we can traverse the tree and find all sorts of fun hierarchical information. Also, we'll create the canonical example model: the blog post. Our models start out looking something like this:

from django.db import models

class NaiveHierarchy(models.Model):
    parent = models.ForeignKey('self', null=True)

    class Meta:
        abstract = True

class BlogPost(NaiveHierarchy):
    title = models.CharField(max_length = 128)
    body = models.TextField()

    def __unicode__(self):
        return self.title

Now let's test to make sure that worked. We'll create some data and test that parent exists on the instances.

>>> from mixins.models import BlogPost
>>> bp = BlogPost.objects.create(title="post1", body="First post!")
>>> bp2 = BlogPost.objects.create(title="post2", body="Second post!", parent=bp)
>>> bp3 = BlogPost.objects.create(title="post3", body="Third post!", parent=bp2)
>>> bp.parent
>>> bp2.parent
<BlogPost: post1>

Inherited Class-Level Methods

So as you can see, everything is working correctly! But that really doesn't save us much time yet, as it's fairly easy to copy and paste fields onto new models, and we still have to write methods which take advantage of those new fields. In this case, I already know that I'm going to want to get the related children and descendants of my blogposts. So why not write those methods on the abstract model? Thanks to inheritance, those methods will apply to the new model as well.

class NaiveHierarchy(models.Model):
    parent = models.ForeignKey('self', null=True)

    def get_children(self):
        return self._default_manager.filter(parent=self)

    def get_descendants(self):
        descs = set(self.get_children())
        for node in list(descs):
            descs.update(node.get_descendants())
        return descs

    class Meta:
        abstract = True

Now, getting all the children or descendents of a particular node is easy:

>>> bp.get_children()
[<BlogPost: post2>]
>>> bp.get_descendants()
set([<BlogPost: post2>, <BlogPost: post3>])

Now this NaiveHierarchy mixin is starting to become quite useful! But what happens if I want to get all of the BlogPosts that have no parents? It's really manager-level functionality. So let's write a manager which defines a get_roots function. Unfortunately, using abstract managers doesn't quite work yet (it works for non-abstract inheritance), but it probably will in future versions of Django. In fact, by applying the latest patch on either Django ticket 7252 or 7154, it will work today. Let's see how this would look:

class NaiveHierarchyManager(models.Manager):
    def get_roots(self):
        return self.get_query_set().filter(parent__isnull=True)

class NaiveHierarchy(models.Model):
    parent = models.ForeignKey('self', null=True)

    tree = NaiveHierarchyManager()

    def get_children(self):
        return self._default_manager.filter(parent=self)

    def get_descendants(self):
        descs = set(self.get_children())
        for node in list(descs):
            descs.update(node.get_descendants())
        return descs

    class Meta:
        abstract = True

class BlogPost(NaiveHierarchy):
    title = models.CharField(max_length = 128)
    body = models.TextField()

    objects = models.Manager()

    def __unicode__(self):
        return self.title

Note that we needed to explicitly define objects as the basic manager, because once a parent class specifies a manager, it gets set as the default manager on all inherited subclasses. This would play out exactly how you would expect:

>>> BlogPost.tree.get_roots()
[<BlogPost: post1>]
>>> BlogPost.tree.all()
[<BlogPost: post1>, <BlogPost: post2>, <BlogPost: post3>]

Advanced Stuff

So now I really wanted to push the limit, and write a mixin which would enhance one of the basic methods of all Model classes: save(). This would be a DateMixin which would contain date_added and date_modified, where date_modified was updated on each save. To my surprise, this Just Worked. Let's see the final result:

import datetime
from django.db import models

class DateMixin(models.Model):
    date_added = models.DateTimeField(default=datetime.datetime.now)
    date_modified = models.DateTimeField()

    def save(self):
        self.date_modified = datetime.datetime.now()
        super(DateMixin, self).save()

class NaiveHierarchyManager(models.Manager):
    def get_roots(self):
        return self.get_query_set().filter(parent__isnull=True)

class NaiveHierarchy(models.Model):
    parent = models.ForeignKey('self', null=True)

    tree = NaiveHierarchyManager()

    def get_children(self):
        return self._default_manager.filter(parent=self)

    def get_descendants(self):
        descs = set(self.get_children())
        for node in list(descs):
            descs.update(node.get_descendants())
        return descs

    class Meta:
        abstract = True

class BlogPost(NaiveHierarchy, DateMixin):
    title = models.CharField(max_length = 128)
    body = models.TextField()

    objects = models.Manager()

    def __unicode__(self):
        return self.title

Conclusions

Mixins can be powerful tools, but there are some hazards in using mixins, which all boil down to the same basic problem: unexpected consequences. In the case of the DateMixin, if any other class has defined a save() method, our custom save() method simply won't be called unless called explicitly. Perhaps this is a documentation problem, but perhaps it's a fault in the idea of a date mixin altogether.

So all that being said, I'm not suggesting to go off and start using any of the mixins that I have provided here, but rather to illustrate how a mixin can be constructed with Django's new Model Inheritance. I do hope that a reusable app emerges with some great mixins that are useful for a large variety of tasks. Because mixins are powerful, and new shiny things that Django can do, and new shiny things are worth being explored!

Inheritance vs. Composition

Lately there's been a lot of discussion in certain programming communities about which method of object extension makes more sense: inheritance, or composition. Most of the time these discussions turn into debates, and when that happens developers tend to "take sides"--often moving towards extremist positions on the issue. I've been sort of quietly thinking about it all lately, trying to determine which use case warrants which approach. Here I show examples of both, explore some properties and consequences of both composition and inheritance, and finally talk about my own preferences.

Examples of Composition and Inheritance

Before talking about the consequences of inheritance vs. composition, some simple examples of both are needed. Here's a simplistic example of object composition (using Python, of course, as our demonstration language):

class UserDetails(object):
    email = "floguy@gmail.com"
    homepage = "http://www.eflorenzano.com"

class User(object):
    first_name = "Eric"
    last_name = "Florenzano"
    details = UserDetails()

Obviously these are not very useful classes, but the essential point is that we have created a namespace for each User object, "details", which contains the extra information about that particular user.

An example of the same objects, modified to use object inheritance might look as follows:

class User(object):
    first_name = "Eric"
    last_name = "Florenzano"

class UserDetails(User):
    email = "floguy@gmail.com"
    homepage = "http://www.eflorenzano.com"

Now we have a flat namespace, which contains all of the attributes from both of the objects. In the case of any collisions, Python will take the attribute from UserDetails.

Consequences

From a pure programming language complexity standpoint, object composition is the simpler of the two methods. In fact, the word "object" may not even apply here, as it's possible to achieve this type of composition using structs in C, which are clearly not objects in the sense that we think of them today.

Another immediate thing to notice is that with composition, there's no possibility of namespace clashes. There's no need to determine which attribute should "win", between the object and the composed object, as each attribute remains readily available.

The composed object, more often than not, has no knowledge about its containing class, so it can completely encapsulate its particular functionality. This also means that it cannot make any assumptions about its containing class, and the entire scheme can be considered less brittle. Change an attribute or method on User? That's fine, since UserDetails doesn't know or care about User at all.

That being said, object inheritance is arguably more straightforward. After all, an e-mail address isn't a logical property of some real-world object called a "UserDetails". No--it's a property of a user--so it makes more sense to make it an attribute on our virtual equivalent, the User class.

Object inheritance is also a more commonly-understood idea. Asking a typical developer about object composition will most likely result in some mumbling and deflection, whereas the same question about object inheritance will probably reveal a whole host of opinions and experience. That's not to say that composition is some sort of dark art, but simply that it's less commonly talked about in so many words.

As more of a sidenote than anything else, inheritance can be speedier in some compiled languages due to some compile-time optimizations vs. the dynamic lookup that composition requires. Of course, in Java you can't escape the dynamic method lookup, and in Python it's all a moot point.

My Preferences

In general, I find object composition to be desirable. I've seen too many projects get incredibly (and unnecessarily) confusing due to complicated inheritance hierarchies. However, there are some cases where inheritance simply makes more sense logically and programmatically. These are typically the cases where an object has been broken into so many subcomponents that it doesn't make sense any more as an object itself.

The Django web framework has an interesting way of dealing with model inheritance, and I think that more projects should follow its example. It uses composition behind the scenes, and then flattens the namespace according to typical inheritance rules. However, that composition still exists under the covers, so that that method may be used instead.

The answer is not going to be "composition always" or "inheritance always" or even any combination of the two, "always". Each has its own drawbacks and advantages and those should be considered before choosing an approach. More research needs to be done on the hybrid approaches, as well, because things like what Django is doing will provide more answers to more people than traditional approaches. Cheers to continued thought about these problems and to challenging conventional thought!

[Link] Django's queryset-refactor branch merged into trunk

This has been a long time coming, and thanks to the incredible efforts of Malcolm Tredinnick and others, Django has just gotten a heck of a lot better!

[Link] django-nyc

A New York City-based Django user group. It's great to see these local Django user groups, and Kevin Fricovsky and Loren Davie seem to be putting a lot of effort into this one. Hopefully this becomes a huge success! If you're a Django enthusiast in NYC, check it out and join in on the discussion.

Lessons Learned

Yesterday I came across a quote from George Patton (via), which stuck me as really insightful, but later something burned the quote directly into my brain.

“A good plan, violently executed now, is better than a perfect plan next week.”

It's a quote which rings quite similar to the commonly-said open source phrase, coined by Eric S. Raymond in his article The Cathedral and the Bazaar.

"Release early. Release often."

The thing which burned these ideas into my brain is the discovery of djangoplugables.com. Simply put: this is an excellent site, which follows the ideas that I mentioned above completely. The premise behind it is essentially to list all of the available django reusable applications on google code, and to display a bit of information about each app.

A group of about 5 people, including myself, have been silently working on a very similar site for the past month or so (the bulk of our work took place during PyCon), but we utterly failed to follow the above sentiment. We debated for hours over how users would be able to submit applications, claim them, and how we could ensure that those claims were accurate. We had tagging, voting, comments, voting ON comments, graphs detailing how "hot" each application was (based on a frequency analysis of the votes over time), and OpenID integration.

But all of this functionality took time, and we implemented it behind closed doors, in a vacuum--without ever seriously focusing on the user interface. I don't know yet what will become of all of our work, but I have a feeling that it will be discontinued in favor of the much better-looking and simpler djangoplugables.com. Maybe we'll see parts of it resurface again, but that's not really the message behind this post. The real message to take away from this experience is that we should practice what we so often preach. In the case of web development, execute the good plan now and iterate, versus trying to perfect everything before release.

The upside of all of this is that our goal has been achieved. What we really wanted to accomplish is what now exists: an excellent resource for finding reusable django applications, and no matter who implements it, that's a win for everyone!

April Fools

April Fool's Day rocks! Maybe I enjoy it because it happens to share the same day as my birthday, but I think it's more to do with the fact that everyone's having fun, being lighthearted, and simply not taking things too seriously. Last year the blog wasn't in any shape to do anything fun for the occasion, but this year it took me about 10 minutes to whip up some middleware fun. That's right, if you can read and understand this right now, the secret is out: a bit of Django middleware is all that's needed to turn your blog into l33t-sp34k central.

I'll even go one step further than telling you how I did it, I'll give you the code:

import re
import lxml.html

trans = {
    'cks': r'xxors',
    'lol': r'r0flc0pt3r',
    'the': r'teh',
    'a': r'4',
    'e': r'3',
    'f': r'ph',
    'g': r'6',
    'h': r'|-|',
    'i': r'1',
    'o': r'0',
    's': r'5',
}

def is_code_block(node):
    return node.attrib.get('class', None) == 'highlight'

def recursive_leetifier(node):
    for child in node.iterchildren():
        if child.text and not is_code_block(child):
            for pattern in trans.iterkeys():
                child.text = re.compile(pattern, re.I).sub(trans[pattern], child.text)
        if not is_code_block(child):
            recursive_leetifier(child)

class LeetSpeakMiddleware(object):
    def process_response(self, request, response):
        try:
            html = lxml.html.fromstring(response.content)
            recursive_leetifier(html)
            response.content = lxml.html.tostring(html)
        except:
            pass
        return response

The idea behind it is simple: Let the request go completely through Django's request/response cycle, and just before returning the correct response, parse the HTML and convert all of the actual content to l33t by doing some simple regular expression substitution. I'm using lxml.html simply because I attended Ian Bicking's talk at Pycon 2008 and was intrigued. I must say that the familiar ElementTree interface helped a lot in getting this code up and running in a short amount of time.

Hopefully you all find this holiday to be as fun as I do, and maybe I'll see some more l33t next year!

[Link] djangosearch

A search app for Django with support for multiple search engines. In alpha state right now, but it's being developed by the people behind Django itself. Looks like it's going to be awesome once it's finished!

[Link] Control FCGI processes through management

Handy snippet for those who are using FCGI and Django together. It brings the fcgi settings away from the command line and into the settings file, making deployment that much easier. I don't personally use FCGI, but if I did, I'd definitely be using this snippet.

[Link] A Faster Django Test Suite

Brian Rosner has implemented a function to run the Django test suite that makes use of multi-cored processors using the awesome processing module. The idea came after he and I were disappointed in the performance of the test suite on an 8-core Mac Pro at the Apple store in Chicago.

About

Vote for your favorite feeds and help their content reach the top! Register now to join in on the fun.

Site News

  • Our crawlers will be turned off while we work on the new version of the site.[...]
  • Updates coming soon so stay tuned.[...]

Channels this feed belongs to: