Модель прокси Django с дополнительными полями модели? - PullRequest
7 голосов
/ 19 августа 2011

Я пишу приложение Django, которое работает как газета. У меня есть статьи, а затем я настроил версии этих статей, которые появляются в определенных контекстах. Таким образом, у меня могла бы быть версия статьи, которая появляется на первой странице газеты, у которой есть более короткая версия оригинального заголовка статьи. Итак, у меня есть:

class Article(models.Model):
    """ A newspaper article with lots of fields """
    title = models.CharField(max_length=255)
    content = models.CharField(max_length=255)

    # Lots of fields...

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

class CustomArticle(Article):
    """ An alternate version of a article """
    alternate_title = models.CharField(max_length=255)

    @property
    def title(self):
        """ use the alternate title if there is one "
        if self.custom_title:
            return self.alternate_title
        else:
            return self.title

    class Meta:
        proxy = True

    # Other fields and methods

К сожалению, я не могу добавить новые поля в прокси:

TypeError: Абстрактный базовый класс, содержащий поля модели, не разрешенные для прокси-модели 'CustomArticle'

Итак, я мог бы сделать что-то вроде этого:

class CustomArticle(models.Model):
    # Other methods...

    original = models.ForeignKey('Article')

    def __getattr__(self, name):
        if hasattr(self.original):
            return getattr(self.original, name)
        else:
            return super(self, CustomArticle).__getattr__(name)

Но, к сожалению, __getattr__, похоже, не работает с моделями Django. Поля в классе Article могут измениться, поэтому нецелесообразно создавать метод @property для каждого из них в CustomArticle. Как правильно это сделать?

Ответы [ 3 ]

2 голосов
/ 20 января 2012

Похоже, это может работать для __getattr__:

def __getattr__(self, key):

    if key not in ('original', '_ original_cache'):
        return getattr(self.original, key)      
    raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, key))
1 голос
/ 24 августа 2011

попробуйте что-то вроде этого:

class CustomArticle(models.Model):
    # Other methods...

    original = models.ForeignKey('Article')

    def __getattr__(self, name):
        return getattr(self.original, name)
1 голос
/ 20 августа 2011

А как насчет того, чтобы сделать CustomArticle подклассом Article?Модели Django поддерживают наследование!Посмотрите на: https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance

...