Ciprian
Ciprian

Reputation: 119

Repeated fields in django models

I need to make a model that has 15 similar fields (let's call them field_01, field_02, field_03, etc.). I also need these fields to be easily available (e.g. to be able to do things like obj.field_01). Because I wanted to get something off the ground really quickly, I just created them the stupid way:

class M (models.Model):
    ....
    field_01 = models.NullBooleanField()
    field_02 = models.NullBooleanField()
    ....

I searched online for a better way to do this. Some people say use setattr, but as far as I could tell from reading and trying some stuff out, this adds attributes to an instance of a class, not the class itself, which means that when I try to attach a model form to this model, it will not see the fields added with setattr. Then I tried overriding the __new__ function, which would allow me to add properties to a class before an instance of that class is created. But I wasn't able to figure out how to do this exactly.

So, what's a way to generate these fields without breaking South and model forms and without copy-paste?

Upvotes: 3

Views: 2553

Answers (3)

Francis Yaconiello
Francis Yaconiello

Reputation: 10919

It sounds like you are looking to have an EAV style database. You should try a library instead of rolling your own. To that end, Django EAV looks pretty awesome. https://github.com/mvpdev/django-eav

To read more about pros and cons of a bunch of libraries to accomplish this check out: https://stackoverflow.com/a/7934577/884453

Upvotes: 0

Chris Pratt
Chris Pratt

Reputation: 239240

It's hard to say definitively without a concrete example of what your doing, but generally, if you find yourself repeating a field, then it's a clear sign for a one-to-many or many-to-many relationship, instead:

One-to-Many

class Field(models.Model):
    m = models.ForeignKey(M, related_name='fields')
    field = models.NullBooleanField()

Many-to-Many

class Field(models.Model):
    field = models.NullBooleanField()

class M(models.Model):
    fields = models.ManyToManyField(Field)

Upvotes: 3

Bernhard Vallant
Bernhard Vallant

Reputation: 50776

Django models have an add_to_class method you could (ab)use for monkey-patching models the way you would like to do.

for i in range(1, 10):
    M.add_to_class('field_%s' % s, NullBooleanField())

Upvotes: 1

Related Questions