如何在Django模型中为类动态设置属性?

如何在Django模型中为类动态设置属性?

问题描述:

我想为模型动态设置属性.这是我的方法.

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!!!

您无法使用 setattr 动态设置它,因为您正在使用Python

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.

自然地,您仍然可以使用诸如Python之类的超级动态语言来执行此操作.但是解决问题的方法需要不同的方法

Naturally, you can still do this in superious dynamic language like Python. But the solution for the problem needs different approach

  • 您可以使用Python 元类和覆盖 __ new __

请参阅SQLAlchemy中的 declared_ attr,这是解决这种特殊情况的独特方式

See declared_attr in SQLAlchemy, its own way to solve this special case