5

I have a long list of 100 labels I need my model to have as fields and to also call in succession to access them in other parts of code. I am going to need to modify them in the future so I would like to be able to do it in one place. Is there a simple way to do this. For example:

labels = ['height', 'weight', 'age']

In models.py

class MyModel(models.Model):
    for label in labels:
        label = models.CharField(max_length=255)

Would the above be equal to :

class MyModel(models.Model):
    height = models.CharField(max_length=255)
    weight = models.CharField(max_length=255)
    age = models.CharField(max_length=255)
5
  • what does "to also call in succession to access them in other parts of code" mean? Does every model have 100 labels? How often are the labels changing? Commented Jul 13, 2014 at 18:20
  • 1
    code.djangoproject.com/wiki/DevModelCreation Commented Jul 13, 2014 at 18:21
  • So the one model will have 100 different fields then I want to be able to call all those fields. For example: [MyModel.field for field in labels]. Commented Jul 13, 2014 at 19:16
  • No, that code is not equivalent. Strings (fortunately) don't automatically convert to symbols Commented Jul 13, 2014 at 19:32
  • 1
    Related Commented Jul 13, 2014 at 21:21

2 Answers 2

12

Django models have an add_to_class method which adds a field (or any attribute, really) to a class. The syntax is MyModel.add_to_class(name, value). The resulting code would be:

class MyModel(models.Model):
    pass

for label in labels:
    MyModel.add_to_class(label, models.CharField(max_length=255))

Internally, this will call the contribute_to_class method on the value passed, if that method exists. Static attributes are added to the class as-is, but fields have this method and all subsequent processing will ensue.

Sign up to request clarification or add additional context in comments.

4 Comments

When would be the best time to call the for loop, not in the model class? In the models.py file? Won't that cause some problems with migrations?
@SimpleSyrup Just after the model definition. It won't cause problems with syncdb/migrations, as the model and its fields are fully defined after the class is imported.
I see. Since python looks at the entire file. Thanks for the tips. This solved my dilema.
Is this considered the most "Pythonic" way to write the code if a Model class contains 20+ attributes?
4

Using locals() should work here:

class MyModel(models.Model):
    for label in labels:
        locals()[label] = models.CharField(max_length=255)

    del locals()['label']

4 Comments

So this is python. making label a local variable for the class. Right?
Oops, it'll actually be exposed as a property at MyClass.label. You'll want to add a del locals()['label'] after that loop to prevent that
I don't understand after the entire loop or in the loop? Wouldn't I want it exposed as that is the behavior that django has by default? Or would it actually try to pull it from the class as opposed to the db?
Without that delete, MyModel.label == 'age', which is not useful to anyone

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.