2009-09-01 3 views
6

Я хотел бы использовать свойства класса Meta наследующей модели для настройки поля, определенного в абстрактной модели, выше дерева наследования:Невозможно использовать класс Meta-класса, наследующий Django, для настройки поля, определенного в унаследованной абстрактной модели.

class NamedModel(models.Model): 
    class Meta: 
     abstract = True 
     verbose_name = 'object' 

    name = models.CharField("Name", 
     max_length=200, 
     db_index=True, 
     help_text="A meaningful name for this %s." % Meta.verbose_name) 
     # see what I'm trying to do here? 
    ) 
    ... 

class OwnedModel(NamedModel): 
    class Meta(NamedModel.Meta): 
     verbose_name = 'owned object' 

Я хотел бы текст справки на поле имени OwnedModel форм сказать «значимое имя этого объекта, принадлежащего». Но это не: слово «принадлежит» отсутствует, что предполагает, что имя verbose_name из NamedModel.Meta используется, когда модель настроена, а не OwnedModel.Meta.

Это не совсем то, что я ожидаю от точки наследования: существует ли какой-то способ создания поля, в котором Meta.verbose_name ссылается на значение на не-абстрактном классе модели, а не на абстрактное на котором было определено поле?

Или я глуп?

(Это может показаться тривиальным примером, и это: но это просто для иллюстрации точки что-то более важным и сложным, я стараюсь делать)

Большое спасибо заранее.

ответ

1

Я думаю, что это происходит потому, что используется Meta.verbose_name и NamedModel.name создается при анализе класса NamedModel. Так что позже, когда класс OwnedModel получает синтаксический анализ, нет никакой возможности что-либо изменить.

Возможно, вы можете установить свойство help_text на OwnedModel.name позже, но это также может изменить имя NamedModel.name.

В подобных ситуациях я поместил переменные части в атрибут класса модели (а не мета), а затем использовал методы/свойства времени выполнения для генерации текстов, которые мне нужны.

+0

Да, я думаю, что это. После выполнения потока я понятнее на жизненном цикле: поля оцениваются при анализе класса, поэтому наследование не рассматривается. И я пробовал атрибуты класса за пределами мета ... той же проблемы, конечно. Я рад переопределить классы полей, и я могу использовать это (+ то, что вы предлагаете), чтобы получить желаемый эффект. –

1

Фактически я закончил делать следующее. Базовой модели получает заданный метод класса dynamic_field_definition(), который может использоваться для исправления полей, аргумент cls является правильным (наследующим) классом. Это означает, что атрибуты cls «Meta» относятся к этому правильному ребенку, а не к исходной базе.

Затем я подключаю этот метод, чтобы получить вызов по сигналу class_prepared, чтобы вы знали, что все готово.

class NamedModel(models.Model): 
    ... 
    @classmethod 
    def dynamic_field_definition(cls): 
     pass 

def dynamic_field_definition(sender, **kwargs): 
    if issubclass(sender, NamedModel): 
     sender.dynamic_field_definition() 
class_prepared.connect(dynamic_field_definition) 

Тогда свойства поля, которые изменяются с моделью класса просто переконфигурировать с помощью этого метода класса (или скорее, как метод переопределен в производных классах).

Это немного взломанный способ принести последний немного OO-ness для моделей Django, но он отлично работает для моей цели.

2

Почему бы вам не попробовать сделать класс.

class BaseNamedModelMeta: 
    abstract = True 
    verbose_name = "your text" 

А потом наследовать и переопределить все, что вы хотите, как это:

class OwnedModel(NamedModel): 
    class Meta(BaseNamedModelMeta): 
     verbose_name = 'owned object' 

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

  • Нет связанных вопросов^_^