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 型のモデル オブジェクトへの参照があり、Dog.speak メソッドではなく、Animal.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 を実装する 1 つの方法は知っていますが、データベース クエリを作成する必要があります。

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 に答える