1

简洁版本:

在Django中使用多表继承,给定一个派生类的模型对象,是否可以在不进行额外的数据库查询的情况下,获取对应的基类模型对象?

长版:

我在我的 Django 应用程序中使用多表继承。我有一种情况,基类定义了某些被派生类覆盖的方法,但我实际上想调用基类方法。这是一个例子:

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()

我知道一种实现 upcast_to_animal 的方法,但它需要进行数据库查询:

def upcast_to_animal(x):
    return Animal.objects.get(pk=x.pk)

我的问题是:是否可以在不对数据库进行额外查询的情况下实现“upcast_to_animal”方法?

4

2 回答 2

4

只是一个简单的演示(向上转换):

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
于 2012-12-19T18:45:35.957 回答
0

怎么样:

import copy

animal = copy.deepcopy(dog)
animal.__class__ = Animal
于 2012-12-19T18:46:17.813 回答