Django:无数据库查询的多表继承和升级
简短版本: 对于Django中的多表继承,给定派生类的模型对象,是否可以在不进行额外数据库查询的情况下获得相应的基类模型对象 长版本: 我在Django应用程序中使用多表继承。在这种情况下,基类定义了某些被派生类重写的方法,但实际上我想调用基类方法。下面是一个例子:Django:无数据库查询的多表继承和升级,django,django-models,Django,Django Models,简短版本: 对于Django中的多表继承,给定派生类的模型对象,是否可以在不进行额外数据库查询的情况下获得相应的基类模型对象 长版本: 我在Django应用程序中使用多表继承。在这种情况下,基类定义了某些被派生类重写的方法,但实际上我想调用基类方法。下面是一个例子: from django.db import models class Animal(models.Model): name = models.CharField(max_length=100) def speak
from django.db import models
class Animal(models.Model):
name = models.CharField(max_length=100)
def speak(self):
return "generic animal noise"
def foo(self):
...
def bar(self):
...
def baz(self):
...
class Dog(Animal):
breed = models.CharField(max_length=100)
def speak(self):
return "Arf"
def foo(self):
...
def bar(self):
...
def baz(self):
...
我有一个对Dog类型的模型对象的引用,我想在它上面调用Animal.speak方法,而不是Dog.speak方法。我知道我可以做到这一点:
dog = Dog.objects.get(name="rover")
Animal.speak(dog)
但是,在我正在编写的代码中,我需要调用多个被重写的方法,因此不需要执行以下操作:
Animal.foo(dog)
Animal.bar(dog)
Animal.baz(dog)
...
我希望能够进行向上转换,然后将所有调用解析为基类的方法:
animal = upcast_to_animal(dog)
animal.foo()
animal.bar()
animal.baz()
我知道一种实现向上转换动物的方法,但它需要进行数据库查询:
def upcast_to_animal(x):
return Animal.objects.get(pk=x.pk)
我的问题是:是否可以在不对数据库进行额外查询的情况下实现向上投射动物的方法?只是一个简单的向上投射演示:
class Animal(models.Model):
name = models.CharField(max_length=30)
def foo(self):
print 'hello animal'
class Dog(Animal):
name_me = models.CharField(max_length=30)
def foo(self):
print 'hello dog'
# django shell
>>> dog = Dog.objects.create(name_me='bull dog')
>>> dog.foo()
hello dog
>>> animal = super(dog.__class__, dog)
>>> animal.foo()
hello animal
只是一个简单的上身示范:
class Animal(models.Model):
name = models.CharField(max_length=30)
def foo(self):
print 'hello animal'
class Dog(Animal):
name_me = models.CharField(max_length=30)
def foo(self):
print 'hello dog'
# django shell
>>> dog = Dog.objects.create(name_me='bull dog')
>>> dog.foo()
hello dog
>>> animal = super(dog.__class__, dog)
>>> animal.foo()
hello animal
那么:
import copy
animal = copy.deepcopy(dog)
animal.__class__ = Animal
那么:
import copy
animal = copy.deepcopy(dog)
animal.__class__ = Animal