Django - Why are variables declared in Model Classes Static
<p>I have been reading and working with Django for a bit now. One of the things that I am still confused with is why the model classes that we create in Django are made up of static variables and not member variables. For instance</p>

<pre><code>class Album(models.Model):
    artist = models.CharField(max_length=128, unique=True)
    title = models.CharField(max_length=128, unique=True)
    genre = models.CharField(max_length=128, unique=True)

    def __unicode__(self):
        return self.name 
</code></pre>

<p>I read <a href="http://stackoverflow.com/questions/68645/static-class-variables-in-python">this</a> page here which explains static and instance variables in python however i am still confused as to why Django wants the field variables in models be static ?</p>

<p>Django uses a <a href="https://docs.python.org/3/reference/datamodel.html#customizing-class-creation" rel="nofollow">metaclass</a> to create the model class. Just as a class's <code>__init__()</code> method creates a new instance, the metaclass's <code>__new__()</code> method creates the class itself. All variables, functions, properties, etc. defined in the class body are passed to the <code>__new__()</code> function. Strictly speaking, just defining a variable in the class body does not create a static/class variable -- only when the <code>__new__()</code> function receives the variable and sets it on the class, will it be a class/static variable. </p>

<p>Django overrides this behavior when it comes to fields and the special <code>Meta</code> inner class, by providing a custom <code>__new__()</code> method. The options in the inner <code>Meta</code> class are converted to an <code>Options</code> instance, and that instance is stored as <code>Model._meta</code> rather than <code>Model.Meta</code>. Similarly, any fields you define are stored in <code>Model._meta.fields</code> rather than as class/static variables. </p>

<p>You will notice that in your example, the class <code>Album</code> does not have a <code>artist</code> attribute: <code>Album.artist</code> will simply raise an <code>AttributeError</code>. This is because the metaclass moves the field from the class to <code>Album._meta.fields</code>. Instances of <code>Album</code> do have an <code>artists</code> attribute, but <em>this is not the field</em>. Instead, it's the database value related to the field. The <code>__init__</code> method of a model uses <code>self._meta.fields</code> to populate any attributes with either the value that is passed to <code>__init__</code>, or with the default value, to assure that the instance variable exists.</p>

<p>Only class variables are passed to the <code>__new__</code> method. If you were to define a field as an instance variable inside <code>__init__</code>, the field would never be passed to <code>Model._meta.fields</code>, and Django simply doesn't know about the field. You will be able to access <code>Album.artist</code>, but this will be the actual field instance, not the related database value. Basically you would be missing the magic that makes a model into a model. </p>

python django