What’s the relation between these two, you may ask. Django, and other frameworks of the sort, try to provide all that stuff that developers could otherwise need to implement over and over in their web applications. They allow to focus on what really differentiates our web apps from the rest of them. In part, this means letting developers focus on the domain model.

Django’s models do this well1, but they are more “relational” than they actually needed to be — we still have to deal with stuff like ForeignKeys and the like.

I would rather think exclusively in terms of objects, but, no ORM can fully abstract the relational database underneath. This is a leaky abstraction that half of the world would like to see fixed, and the other half as actually tried to fix it but failed to varying degrees. And that’s why I understand why django’s approach has converged to what it is today. It reflects a reasonable balance of these forces.

I still think there are better names than ForeignKey to represent one-to-many associations, though.

Creating and visualizing django models

Even if not purely object-oriented in their nature, I still think of django models as object-oriented domain entities. And the domain model of a system can really grow beyond the point where it can fit in a single person’s mind. Django projects are no exception.

So, I’ve been trying to find a tool that helps me dealing with large django projects. Here are some of my findings:

  • UML-to-Django —Uses XSL to transform a XMI file, to Django model classes. It has a few limitations at this point. Namely, it works well when the source XMI is created by ArgoUML, but I couldn’t use it successful with class models exported from other tools. I’m currently using Visual Paradigm, and the best way I found to bring my model to UML-to-django was to make Visual Paradigm generate Java source-code, and reverse engineer it in ArgoUML. And this still required a little bit of fiddling with the XMI produced by ArgoUML, but it worked in the end.
  • Dia-to-Django — Didn’t try it, as the SVN repo seems to have gone the way of the Dodo, but it looks like it could have been a viable alternative to UML-to-Django.
  • GraphModels extension — Rather than allow to generate django models from a UML class diagram, the graphmodels extension allows to visualize a django project as a diagram. Not a bad option; one can definitely understand a django project much quicker than looking at a diagram of the model classes. Unfortunately the notation is much closer to the relational world than to a object oriented one. Not that there’s anything wrong with that, but the visual elements of a class diagram convey a richer semantics, and I do take more time to grasp a diagram of this kind than I take to grasp a class diagram.
  • Django-yuml — Creates UML class diagrams from django models, using yuml. It’s obviously limited to what yUML can express, and as such it can’t represent stuff like association classes. Django models can express associative classes using the through option.
  • DUDE: Django UML Designer — This one is very different from the previous tools, but interesting nonetheless. Its a django-based UML modeler. It’s a dead project, apparently, but in case you’re interested in this kind of stuff, check models.py for a very early implementation of MOF using django model classes.

The graphmodels extension is serving me good for now, after some hacking to make the generated diagrams closer to UML class diagrams. Here’s an example of how it looks for the pycon system source code:

PyCon Models using the graph_models extension

Here’s how it looked before the modifications:

PyCon Models using the graph_models extension

This example doesn’t have generalizations, which also look much nicer with my changes. Here’s an example of how they look using my patch, before and after respectively:

A simple example of using the django's graph_models extension.A simple example of using the django's graph_models extension using my patch.

Update 2011/09/23: Fixed big mixup with the pictures.

  1. And I could start another rant right here, as I see a model as a set of classes/domain-entities, and not a single class/domain-entity. But I will try to adopt django’s terminology for the duration of this post.