2014-12-16 2 views
2

У меня есть класс Base для многих подклассов, и единственное, что меняется в подклассах, это определенный метод (шаблон шаблона). Однако я застрял и не могу заставить его работать.Любой способ использования модели Django в качестве интерфейса?

class Base(models.Model): 
    _value = models.CharField(max_length=200) 
    _name = models.CharField(max_length=200) 
    user = models.ForeignKey(User, related_name="some_set") 

    #used as a property 
    def value(): 
     def fget(self): 
      self.refresh() 
      return self._value 

    def refresh(self): 
     raise NotImplementedError("..") 

class Subclass1(Base): 
    def refresh(self): 
     self._value = some_val 

class Subclass2(Base): 
    def refresh(self): 
     self._value = some_other_val 

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

for x in user.some_set.all(): 
    print x.value 

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

ответ

0

Я закончил с использованием шаблона стратегии с GenericForeignKey

class Base(models.Model): 
    _name = models.CharField(max_length=200) 
    user = models.ForeignKey(User, related_name="some_set") 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    strategy = GenericForeignKey() 

    #used as a property 
    def value(): 
     def fget(self): 
      return self.strategy.value 

class Strategy1(models.Model): 
    #some other definitions 
    def value(): 
     def fget(self): 
      return some_var 

class Strategy2(models.Model): 
    #some other definitions 
    def value(): 
     def fget(self): 
      return some_other_var 

что позволило мне сделать for x in user.some_set.all(): print x.value

+1

посмотрите https://github.com/saxix/django-strategy-field – sax

1

Возможно, мне не хватает точки, но вы пробовали Django Model Utils?

https://bitbucket.org/carljm/django-model-utils/src

Если вы посмотрите на менеджера наследования и внести соответствующие изменения в вашей модели, то вы должны иметь возможность запрашивать в соответствии с:

entities = Base.objects.filter(user=my_user_obj).select_subclasses() 
for entity in entities: 
    print entity.value 
+0

Это близко, но я не могу заставить его решить на самом глубоком уровне подкласс. Когда я помещаю InteritanceManager в подкласс (у меня на самом деле есть 2 уровня в глубину), он не разрешает подклассы –

+0

Насколько глубоко ваше наследование модели? – justcompile

+0

Один дополнительный уровень, чем выше, извините, должен был включить это. –

4

использования Proxy Models

из doc

Иногда, однако, вы хотите изменить поведение модели Python - возможно, изменить менеджер по умолчанию или добавить новый метод.

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

+0

Это на правильном пути, но все же не позволяет мне вызвать новый определенный метод 'refresh' при получении соответствующего набора. –