Geo
Geo

Reputation: 96987

Django models & Python class attributes

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?

Upvotes: 9

Views: 3620

Answers (4)

remosu
remosu

Reputation: 5119

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

Upvotes: 0

Olivier Verdier
Olivier Verdier

Reputation: 49256

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!

Upvotes: 2

miku
miku

Reputation: 188224

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.

Upvotes: 7

Daniel Roseman
Daniel Roseman

Reputation: 600059

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

Upvotes: 2

Related Questions