2009-07-06 4 views
29

Я пишу mixin, который позволит моим моделям легко перевести их в глубокий dict значений (вроде как .values ​​(), но пересекающихся отношений). Чистейшее место для определения этих, как представляется, в моделях себя, а-ля:Добавление атрибутов в мета-класс Django Model

class Person(models.Model, DeepValues): 
    name = models.CharField(blank=True, max_length=100) 
    tribe = models.ForeignKey('Tribes') 

    class Meta: 
     schema = { 
      'name' : str, 
      'tribe' : { 
       'name' : str 
      } 
     } 

Person.objects.all().deep_values() => { 
    'name' : 'Andrey Fedorov', 
    'tribe' : { 
     'name' : 'Mohicans' 
    } 
} 

Однако, Django жалуется мой в том числе это в class Meta с:

TypeError: 'class Meta' got invalid attribute(s): schema 

(всего трассировки стека here)

Теперь, я полагаю, я мог бы тщательно переопределить это в своем микшинге, но есть ли более элегантный способ хранения этой информации?

ответ

45

Я не знаю о элегантно, но один прагматичный путь:

import django.db.models.options as options 

options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('schema',) 

Очевидно, что это нарушило бы, если Django никогда не добавил «схемы» атрибут самостоятельно. Но эй, это мысль ... вы всегда можете выбрать имя атрибута, которое вряд ли столкнется.

+5

Для потомков это не работает, но это делало: options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('default_values',) –

+2

Ох ... это, по-видимому, потому, что мое решение преобразует DEFAULT_NAMES в список, тогда как ваша доработка держит его как кортеж. –

+0

Скорее всего! :) –