Good habits I learnt from Django


Django has various good features I’ve previously mentioned. While they can’t be taken out and applied to other languages like PHP right away, it also has some nice ways of doing things that can be taken and used elsewhere.

Let’s look at some good habits I took from Django and started using in PHP, that could benefit you too.

URL generation

In Django, you can define a method called get_absolute_url to your models, which should return an absolute URL to the model in question.

You usually might just type the URLs manually, perhaps putting some variable from the record as a parameter to the URL, or if you’re using something like Zend Framework, you probably would be using the URL helper. In any case, you would be hardcoding some values in your views.

Using an URL generation method in the model is a great idea. It takes away this hardcoded feature, in case your URLs change, and they might. It can also reduce the clutter of your views when you don’t need to put params to urls in long syntax and such.

Here’s an example with Zend Framework and Doctrine:

class MyModel extends Doctrine_Record
    /* the usual setUp and setTableDefinition stuff here */
    public function getAbsoluteUrl()
        $helper = Zend_Controller_Action_HelperBroker::getStaticHelper('Url');
        return $helper->url(array(
            'module' => 'example',
            'controller' => 'mycontroller',
            'action' => 'show',
            'id' => $this->id
        ), 'default', true);

Of course, it might be even better idea to use a named route and only passing in the ID or some other property of the record.

Models to strings

This is more of a small convenience than anything else, but I think it’s still a nice idea. Django encourages you to put __unicode__ methods in your models, which should return a human readable text representation of the record – similar to what you can do with PHP’s __toString.

This is quite useful if you need to output textual representations of models, without necessarily knowing what kind of model you’re dealing with; if you don’t know what model it is, you don’t know what fields it has. By simply adding a method that outputs something meaningful, you can overcome this problem:

class MyModel extends Doctrine_Record
    public function __toString()
        return $this->name;

I think __toString is an often overlooked PHP feature. It isn’t really used anywhere, so people don’t think of it. In languages like C#, ToString is used more, starting from the Visual Studio IDE, to display useful representations of things.

Application structure != URL structure

Since I’ve been using Zend Framework a lot, I had already fallen into it’s way of thinking about URLs. By default, ZF gives you the following URL scheme: /module/controller/action. This means it’s very easy to get nice URLs without doing anything except naming your modules, controllers and actions in a fashion that makes the URLs look good.

In Django, there are no predefined URL behaviors. You will need to define all URLs by hand, and at first it felt that it must be a lot of work, but in reality it is not that much.

While Zend Framework’s way of giving you default URL behavior can speed up getting started, it can also make you think of your application in terms of your URL…

“I want this list of big robots fighting in space show up under /japan/big-robots/in-space, so I’m going to put it in the Japan module, under BigRobotsController’s inSpaceAction”

So while it would be quite obvious where the code for the URL is if you ever wanted to edit it, it might be a much better idea to create a CategoryController and add a listAction to it, which would take big-robots and in-space as parameters.

Creating different kinds of URLs like this is definitely possible in ZF, but especially beginning ZF-devs seem to be falling for the easy default URL handling.

In closing

I can say it is definitely useful to look into other frameworks and languages than the one you’re usually dealing with. There’s a lot of things you can learn from them.