title: Programmatically specifying Django model attributes
body: <p>I would like to add attributes to a Django models programmatically. At class creation time (the time of the definition of the model class). The model is not going to change after that in run time. For instance, lets say I want to define a <code>Car</code> model class and want to add one <code>price</code> attribute (database column) per currency, given a list of currencies. (This list of currencies should be considered a constant that won't change runtime. I don't want a related model for these prices.)</p>
  
  <p>What would be the best way to do this?</p>
  
  <p>I had an approach that I thought would work, but it didn't exactly. This is how I tried doing it, using the car example above:</p>
  
  <pre><code>from django.db import models
  
  class Car(models.Model):
      name = models.CharField(max_length=50)
  
  currencies = ['EUR', 'USD']
  for currency in currencies:
      Car.add_to_class('price_%s' % currency.lower(), models.IntegerField())
  </code></pre>
  
  <p>This does seem to work pretty well at first sight:</p>
  
  <pre><code>$ ./manage.py syncdb
  Creating table shop_car
  
  $ ./manage.py dbshell
  shop=# \d shop_car
                                    Table "public.shop_car"
    Column   |         Type          |                       Modifiers                       
  -----------+-----------------------+-------------------------------------------------------
   id        | integer               | not null default nextval('shop_car_id_seq'::regclass)
   name      | character varying(50) | not null
   price_eur | integer               | not null
   price_usd | integer               | not null
  Indexes:
      "shop_car_pkey" PRIMARY KEY, btree (id)
  </code></pre>
  
  <p>But when I try to create a new Car, it doesn't really work anymore:</p>
  
  <pre><code>&gt;&gt;&gt; from shop.models import Car
  &gt;&gt;&gt; mycar = Car(name='VW Jetta', price_eur=100, price_usd=130)
  &gt;&gt;&gt; mycar
  &lt;Car: Car object&gt;
  &gt;&gt;&gt; mycar.save()
  Traceback (most recent call last):
    File "&lt;console&gt;", line 1, in &lt;module&gt;
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/base.py", line 410, in save
      self.save_base(force_insert=force_insert, force_update=force_update)
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/base.py", line 495, in save_base
      result = manager._insert(values, return_id=update_pk)
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/manager.py", line 177, in _insert
      return insert_query(self.model, values, **kwargs)
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/query.py", line 1087, in insert_query
      return query.execute_sql(return_id)
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/sql/subqueries.py", line 320, in execute_sql
      cursor = super(InsertQuery, self).execute_sql(None)
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/sql/query.py", line 2369, in execute_sql
      cursor.execute(sql, params)
    File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/backends/util.py", line 19, in execute
      return self.cursor.execute(sql, params)
  ProgrammingError: column "price_eur" specified more than once
  LINE 1: ...NTO "shop_car" ("name", "price_eur", "price_usd", "price_eur...
                                                               ^
  </code></pre>
  
  <p>Apparently, though, my code seem to run several times, causing the "price_eur" attribute to be added several times.</p>
  
  <p>Comment: Initially I used the wording "at run time" ("I would like to add attributes to a Django models programmatically, at run time."). This wording wasn't the best. What I really want to was to add those fields at "model definition time" or "class creation time".</p>