Thursday, October 3, 2013

A small example of Django's elegance

Python is an interactive language, thanks to its REPL. And since it's free from typing constraints that weigh down languages like Java, you're free to design an API that is as flexible and easy to understand as you desire.

Want to introspect a field on your Django model? Easy!! Say you have a Foo model and a bar field you want to get.

Something like this:

class Foo(Model):
    bar = CharField(max_length=25)

Let's try and access that bar field!

>>> Foo.bar
AttributeError: type object 'Foo' has no attribute 'bar'

Hm! Well... Huh. Look at that. Take two?

>>> Foo._meta.get_field_by_name('bar')
(<django.db.models.fields.CharField: bar>, None, True, False)

...Right, of course. The old "None, True, False" flags.

>>> Foo._meta.get_field_by_name('bar')[0]
<django.db.models.fields.CharField: bar>

There's that famous Python elegance. That's why they call it executable psuedocode, folks. What do those flags even do? Django's got documentation of famous quality, so let's see what those extra values mean!

https://docs.djangoproject.com/search/?q=_meta&release=7

Hm. Well. Well it's not documented. But they do use it in examples in their documentation. Hm. Well there is that good ol' REPL.

>>> help(Foo._meta.get_field_by_name)
get_field_by_name(self, name) method of django.db.models.options.Options instance
    Returns the (field_object, model, direct, m2m), where field_object is
    the Field instance for the given name, model is the model containing
    this field (None for local fields), direct is True if the field exists
    on this model, and m2m is True for many-to-many relations. When
    'direct' is False, 'field_object' is the corresponding RelatedObject
    for this field (since the field doesn't have an instance associated
    with it).
    
    Uses a cache internally, so after the first access, this is very fast.

Ah of course. That explains it all. That's what I like about Python. Clear, simple, and easy to use. Of course you find those exact same values all across their community, like in Kenneth Reitz's requests library. Or Django. Right?