views:

56

answers:

4

The tutorial on the django website shows this code for the models:

from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice = models.CharField(max_length=200)
    votes = models.IntegerField()

Now, each of those attribute, is a class attribute, right? So, the same attribute should be shared by all instances of the class. A bit later, they present this code:

class Poll(models.Model):
    # ...
    def __unicode__(self):
        return self.question

class Choice(models.Model):
    # ...
    def __unicode__(self):
        return self.choice

How did they turn from class attributes into instance attributes? Did I get class attributes wrong?

+1  A: 

It's done with metaclasses - very clever stuff. I'd recommend Marty Alchin's excellent book Pro Django if you want to learn more.

Daniel Roseman
+3  A: 

Have a look at the Model class under django/db/models.py. There the class attributes are turned to instance attributes via something like

setattr(self, field.attname, val)

One might recommend the whole file (ModelBase and Model class) as an excellent hands-on example on metaclasses.

The MYYN
+1  A: 

In Python, a class attribute is always also an instance attribute:

class C(object):
    a = 1
    def show_a(self):
        print self.a # <- works

But in django it is further complicated by the fact that Model classes have special metaclasses, so be careful to your assumptions!

Olivier
A: 

A class instance has a namespace implemented as a dictionary which is the first place in which attribute references are searched.

http://docs.python.org/reference/datamodel.html

remosu