2014-01-05 140 views
1

我想在models.py中动态指定模型字段。例如:如何动态添加模型字段?

class ModelA(models.Model): 
    pass # whatever 
# immediately after class declaration in models.py 
if django_is_not_non_rel: 
    MyModel.all_modelb = models.ManyToManyField(ModelB, through="ModelAB") 

但此代码示例不起作用。当条件成立时,ModelA在所有事物初始化后都没有all_modelb字段。为什么????我如何影响我的意图?

+0

你为什么要做这个? –

+0

我试图让我的例子尽可能简单。真实情况是只有在特定条件成立时才添加动态模型字段。在我的情况下,该字段是一个ManyToManyField,如果Django框架是NonRel,则不会添加...您有解决方案吗? – jacob

+0

为什么不在模型中添加字段,并在条件为真的情况下向其添加关系? AFAIK,特定模型的所有实例应该具有相同的字段。 (但我没有那种经验与Django .. :) –

回答

2

使用Django动态创建列并非不可能,但您必须使用元类和/或继承来实现。

您的问题最简单的解决方案可能会是这样的:

if django_is_not_non_rel: 
    class ModelABase(models.Model): 
     MyModel.all_modelb = models.ManyToManyField(ModelB, through="ModelAB") 

     class Meta: 
      abstract = True 

else:   
    class ModelABase(models.Model): 
     class Meta: 
      abstract = True 

class ModelA(ModelABase): 
    pass # whatever 

或者也可以简单(如果你并不需要尽可能多的定制):

class ModelAORMBase(models.Model): 
    MyModel.all_modelb = models.ManyToManyField(ModelB, through="ModelAB") 

    class Meta: 
     abstract = True 

if django_is_not_non_rel: 
    ModelABase = ModelAORMBase 
else: 
    ModelABase = models.Model 

class ModelA(ModelABase): 
    pass # whatever 
+0

谢谢@wolph。你的解决方案似乎是最简单的,并且避免了元类的复杂性。 – jacob

+1

@jacob:我已经添加了一个替代版本,可能在将来更具可读性:) – Wolph

+0

再次感谢@wolph。是的,你的第二个版本更简单一些。 – jacob