Наследование модели Джанго на поле другой модели

У меня есть следующие модели:

class Engine(models.Model):
    ...
    def speed(self):
        return 100
    objects = InheritanceManager()

class TurboEngine(Engine):
    ...
    def speed(self):
        return 500

class Car(models.Model):
    ...
    engine = models.ForeignKey(Engine)

Нет, я использую DetailView на Car с TurboEngine, но car.engine.speed() возвращает 100. Как мне сделать так, чтобы он выбрал правильный класс?

1 ответ

Решение

Это очень хороший и интересный вопрос, у нас была такая же проблема 2 или 3 года назад:

class RealInstaceProvider(object):
    def get_real_instance(self):
        """
        Makes a SQL sentence which does the JOIN with its real model class
        """

        if hasattr(self, '_real_instance'):  # try looking in our cache
            return self._real_instance
        subclasses = self.__class__.__subclasses__()
        if not subclasses:  # already real_instance
            real_instance = getattr(self, self.__class__.__name__, self)
            self._real_instance = real_instance
            return real_instance
        else:
            subclasses_names = [cls.__name__.lower() for cls in subclasses]
            for subcls_name in subclasses_names:
                if hasattr(self, subcls_name):
                    self._real_instance = getattr(self, subcls_name, self).get_real_instance()
                    return self._real_instance
            self._real_instance = self
            return self

class Engine(models.Model, RealInstaceProvider):
    ...
    def speed(self):
        return 100
    objects = InheritanceManager()

class TurboEngine(Engine):
    ...
    def speed(self):
        return 500

class Car(models.Model):
    ...
    engine = models.ForeignKey(Engine)

И вы должны получить доступ следующим образом: car.engine.get_real_provider(). Speed ​​()

Другие вопросы по тегам