2014-01-05 4 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

Смежные вопросы