Reputation: 4912
I want to dynamically set attribute to models. Here is the way I did it.
# models.py
class pwr(models.Model):
# test info
tester = models.CharField(max_length=10)
test_date = models.DateField(verbose_name='Test Date')
test_summary = models.TextField(verbose_name='Test Summary')
test_duration = models.CharField(max_length=20, verbose_name='Test Duration')
for i in xrange(2):
ii = str(i)
test_result = 'test_result_' + ii
test_com = 'test_comment_' + ii
bug_level = 'bug_level_' + ii
bug_id = 'bug_id_' + ii
bug_sum = 'bug_summary_' + ii
exec (test_result + "= models.CharField(max_length=20, verbose_name='Result', \
choices=(\
('Pass', 'P'), \
('Fail', 'F'), \
('Not Test', 'N/T'), \
('Not Avaliable', 'N/A'), \
('Reference', 'Ref'), \
('Warn', 'W')\
))")
exec (test_com + "= models.CharField(max_length=100, verbose_name='Comment', blank=True)")
exec (bug_level + "= models.CharField(max_length=100, verbose_name='Bug Level', blank=True, \
choices=(('1', '1:Blocker'), \
('2', '2:Critical'), \
('3', '3:Major'), \
('4', '4:Normal'), \
('5', '5:Enhancement')))")
exec (bug_id + "= models.CharField(max_length=10, verbose_name='Bug ID', blank=True)")
exec (bug_sum + "= models.CharField(max_length=100, verbose_name='Bug Summary', blank=True)")
# When I tried to use setattr here, no 'test_attribute' field is added to table pwr in database
setattr(pwr, 'test_attribute', models.CharField(max_length=10, verbose_name='test attr', blank=True))
This seems really ugly.. Do you have any better solution for this? Thanks!!!
Upvotes: 1
Views: 3018
Reputation: 83706
You cannot set it dynamically with setattr
because you are dealing with Python descriptors, not attributes. This is because of the order of events when the module is imported and Python class ans descriptors put together.
Naturally, you can still do this in superious dynamic language like Python. But the solution for the problem needs different approach
You can use Python metaclasses and override __new__
See declared_attr in SQLAlchemy, its own way to solve this special case
Upvotes: 2