Django magic with ForeignKeys

Discovered interesting stuff yesterday. Actually it should've been apparent. So when we add a ForeignKey to a Django Model, the model itself creates an attribute for the key name and appends "_id" in the field. This has been documented here. However the documentation says that it's done on the DB side.

Turns out it is done on the python side as well. So it actually creates an attribute on the ForeignKey and appends it to the class instance. What does that mean for us? We can't use it as a property. Example:

class Foobar(models.Model):  
    field1 = models.CharField(max_length=10)
    field2 = models.ForeignKey(SomeOtherClass)\

    @property
    def field2_id(self):
        return "%s" % self.field2 + 1

So it'll raise an error saying can't set Attribute. It's the same error that you get when you assign a @property decorator to a field that exists on the Class. So say if I did:

class Foobar(models.Model):  
    field1 = models.CharField(max_length=10)
    field2 = models.ForeignKey(SomeOtherClass)

    @property
    def field1(self):
        return "%s" % self.field2 + 1

This would raise the same kind of exception. So interesting discovery.

Another thing that wasn't apparent. You can't render fields with underscore before them in the templates. When I say render I mean can't use them within {{ }}. So, things like, {{ _field2_id }} won't fly. But interestingly, {% include "_some_template.html" %} will work just fine.

I still haven't spoken to the IRC channel about this, but I might.