Programmatically specifying Django model attributes

Posted by mojbro on Stack Overflow See other posts from Stack Overflow or by mojbro
Published on 2010-03-23T15:30:39Z Indexed on 2010/03/23 15:33 UTC
Read the original article Hit count: 570

Filed under:
|
|

Hi!

I would like to add attributes to a Django models programmatically, at run time. For instance, lets say I have a Car model class and want to add one price attribute (database column) per currency, given a list of currencies.

What is the best way to do this?

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:

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())

This does seem to work pretty well at first sight:

$ ./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)

But when I try to create a new Car, it doesn't really work anymore:

>>> from shop.models import Car
>>> mycar = Car(name='VW Jetta', price_eur=100, price_usd=130)
>>> mycar
<Car: Car object>
>>> mycar.save()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  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...
                                                             ^

© Stack Overflow or respective owner

Related posts about django

Related posts about django-models