Creating dynamic models?

9 views
Skip to first unread message

Kevin Renskers

unread,
Nov 24, 2009, 8:35:06 AM11/24/09
to Django users
Hi all,

In my Django project I want to have a model that is dynamically
created. I tried using the __init__ function for this, something like
so:

fields = ['field_a', 'field_b', 'field_c']

class MyModel(models.Model):
def __init__(self, *args, **kwargs):
for field in fields:
setattr(self, field, models.DecimalField(decimal_places=4,
max_digits=10))

Sadly, this doesn't work. The columns don't get created when you run
the syncdb command, and even something like
MyModel._meta.get_all_field_names() doesn't return the dynamic fields.

So, is there a way I can create a "dynamic" model? I did come across
http://code.djangoproject.com/wiki/DynamicModels but I don't really
get that. It looks so much different then normal models, it seems like
I would loose a lot of functionality or would have to change a lot of
code somewhere else in my application?

Hopefully there is an easy way to do this :)

Cheers,
Kevin

Kevin Renskers

unread,
Nov 26, 2009, 3:56:21 AM11/26/09
to Django users
Just a small update: the DynamicModels way as described on the wiki
doesn't work (it also says that it only works in Django 0.96, so
yeah..).

If anyone has any idea how to do this, I would be very thankful!


On Nov 24, 2:35 pm, Kevin Renskers <i...@bolhoed.net> wrote:
> Hi all,
>
> In my Django project I want to have a model that is dynamically
> created. I tried using the __init__ function for this,  something like
> so:
>
> fields = ['field_a', 'field_b', 'field_c']
>
> class MyModel(models.Model):
>     def __init__(self, *args, **kwargs):
>         for field in fields:
>             setattr(self, field, models.DecimalField(decimal_places=4,
> max_digits=10))
>
> Sadly, this doesn't work. The columns don't get created when you run
> the syncdb command, and even something like
> MyModel._meta.get_all_field_names() doesn't return the dynamic fields.
>
> So, is there a way I can create a "dynamic" model? I did come acrosshttp://code.djangoproject.com/wiki/DynamicModelsbut I don't really

Matthias Kestenholz

unread,
Nov 26, 2009, 4:14:32 AM11/26/09
to django...@googlegroups.com
I can see two ways to achieve what you seem to want:

1. Add fields after the model has been created

This method uses an only unofficially documented feature[1] of
Django's model field classes.

class MyModel(models.Model):
# a few fields

for field in fields:
MyModel.add_to_class(field, models.DecimalField(decimal_places=4,
max_digits=10))



2. Construct a new type dynamically

class Meta:
verbose_name = _('my model')

attrs = {
'__module__': 'mymodule',
'Meta': Meta,
'method1': method1,
# ... more fields and methods
}

for field in fields:
attrs[field] = models.DecimalField(...)

MyModel = type('MyModel', (models.Model,), attrs)




Of course, the usual caveats apply. It might make your code harder to
read and understand, and harder to debug too, because it is not clear
what model fields exist by simply looking at the model code (that
applies especially to method 1)


Matthias

[1]: It's documented in Marty Alchin's excellent Pro Django book. I
think we can assume that this method won't go away without very good
reasons(tm).

Kevin Renskers

unread,
Nov 26, 2009, 4:23:22 AM11/26/09
to Django users
Hi Matthias ,

Thank you, I went for option 1 and it works perfectly!

Funny, the add_to_class function basically does "setattr(cls, name,
value)". So I had the right solution, only you have to do this after
class creation, not inside its __init__ function. Good to know, will
blog about this :)

Again, thank you very much.

Cheers,
Kevin


On Nov 26, 10:14 am, Matthias Kestenholz
<matthias.kestenh...@gmail.com> wrote:
> On Thu, Nov 26, 2009 at 9:56 AM, Kevin Renskers <i...@bolhoed.net> wrote:
> > Just a small update: the DynamicModels way as described on the wiki
> > doesn't work (it also says that it only works in Django 0.96, so
> > yeah..).
>
> > If anyone has any idea how to do this, I would be very thankful!
>
> > On Nov 24, 2:35 pm, Kevin Renskers <i...@bolhoed.net> wrote:
> >> Hi all,
>
> >> In my Django project I want to have a model that is dynamically
> >> created. I tried using the __init__ function for this,  something like
> >> so:
>
> >> fields = ['field_a', 'field_b', 'field_c']
>
> >> class MyModel(models.Model):
> >>     def __init__(self, *args, **kwargs):
> >>         for field in fields:
> >>             setattr(self, field, models.DecimalField(decimal_places=4,
> >> max_digits=10))
>
> >> Sadly, this doesn't work. The columns don't get created when you run
> >> the syncdb command, and even something like
> >> MyModel._meta.get_all_field_names() doesn't return the dynamic fields.
>
> >> So, is there a way I can create a "dynamic" model? I did come acrosshttp://code.djangoproject.com/wiki/DynamicModelsbutI don't really
Reply all
Reply to author
Forward
0 new messages