人類已知的唯一方法是使用Metaclass編程。
這裏是簡短的回答:
from django.db.models.base import ModelBase
class InheritanceMetaclass(ModelBase):
def __call__(cls, *args, **kwargs):
obj = super(InheritanceMetaclass, cls).__call__(*args, **kwargs)
return obj.get_object()
class Animal(models.Model):
__metaclass__ = InheritanceMetaclass
type = models.CharField(max_length=255)
object_class = models.CharField(max_length=20)
def save(self, *args, **kwargs):
if not self.object_class:
self.object_class = self._meta.module_name
super(Animal, self).save(*args, **kwargs)
def get_object(self):
if not self.object_class or self._meta.module_name == self.object_class:
return self
else:
return getattr(self, self.object_class)
class Dog(Animal):
def make_sound(self):
print "Woof!"
class Cat(Animal):
def make_sound(self):
print "Meow!"
和期望的結果:
shell$ ./manage.py shell_plus
From 'models' autoload: Animal, Dog, Cat
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> dog1=Dog(type="Ozzie").save()
>>> cat1=Cat(type="Kitty").save()
>>> dog2=Dog(type="Dozzie").save()
>>> cat2=Cat(type="Kinnie").save()
>>> Animal.objects.all()
[<Dog: Dog object>, <Cat: Cat object>, <Dog: Dog object>, <Cat: Cat object>]
>>> for a in Animal.objects.all():
... print a.type, a.make_sound()
...
Ozzie Woof!
None
Kitty Meow!
None
Dozzie Woof!
None
Kinnie Meow!
None
>>>
它是如何工作的?
有關類 動物的名字
- 存儲信息 - 我們使用 object_class爲
- 去掉「代理」元屬性 - 我們需要在Django( 反向關係,這個壞 方面,我們創造額外DB 表每一個兒童模型和 浪費額外的DB命中爲, 好的一面,我們可以添加一些孩子 模型相關字段)
- 自定義保存()動物拯救類 調用保存的對象 的object_class中的名稱。
- 方法get_object需要通過在Django 中通過反向關係引用 與名稱緩存在 object_class中的Model。
- 做這個.get_object()自動「投射」 每次動物被實例化 重新定義動物的Metaclass 模型。 Metaclass就像一個 類的模板(就像 類是一個對象的模板)。關於元類Python中
的更多信息:http://www.ibm.com/developerworks/linux/library/l-pymeta.html
您可以應用make_sound動物模型,並添加聲音= models.charField()到它。 – monkut 2010-02-08 01:22:54
我的例子很簡單 - 我想要做的事情需要一堆取決於類型的工作,並且不能與模型一起存儲。 – sotangochips 2010-02-08 04:26:23