Не удается использовать мета-класс наследуемой модели Django для настройки поля, определенного в унаследованной абстрактной модели - PullRequest
6 голосов
/ 01 сентября 2009

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

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 ссылается на значение в классе неабстрактной модели, а не на абстрактное значение в какое поле было определено?

Или я ненормальный?

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

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

Ответы [ 3 ]

2 голосов
/ 23 мая 2016

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

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

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

class OwnedModel(NamedModel):
    class Meta(BaseNamedModelMeta):
        verbose_name = 'owned object'
1 голос
/ 01 сентября 2009

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

Затем я подключаю этот метод для вызова метода 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)

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

Это немного хакерский способ привнести последние мелочи в модели Django, но он отлично работает для моей цели.

1 голос
/ 01 сентября 2009

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

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

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

...