0

假设我的模型设置如下:

class B(Model):
        ...
        def __str__(self):
                return "B"
class C(B):
        ...
        def __str__(self):
                return "C"
class A(Model):
        b = ForeignKey(B)

        def __str__(self):
                print "A: %s"%(self.b)

a = A(b=C(...))
a.save()
print str(a) # Prints "A: B"

也许我有点困惑 django 继承是如何工作的。我的意图是让程序"A: C"在运行时打印(因为A.b是 model 的一个实例C

我想我可能会问多表继承。但这只有在你知道你想要的子类的实例的情况下。

作为我感到困惑的另一个例子,我想从文档中借用这个例子:

# Assume Restaurant, Park, and Museum inherit Place
bills = Restaurant.objects.create(name="Bill's Pub", burger="Bill's Burger")
city_prk = Park.objects.create(name='City Park', num_trails=5)
nose = Museum.objects.create(name='Nose Museum', est=1940)

places = Places.objects.all()

我肯定会得到 3 个对象(类型Place)的列表,但我无法区分地点的类型。例如,如果我想打印出每个地方的 str 值......

for place in places:
    print str(place)

...python 只会执行Place.__str__()而不是Restaurant.__str__()(对于餐厅)或Park.__str__()(对于公园)。“普通”python似乎不会发生这种情况。Python 通常应该自动找到最低继承的类并从中执行被覆盖的函数(如果 B 覆盖了 A 的方法,则将执行 B 的方法)。

我的假设正确吗?很抱歉这个问题很长(如果不清楚,很抱歉)。我不完全确定如何问我在想什么。

4

2 回答 2

0

你说得对,大多数 python 对象都是这样工作的,但 django 模型却没有。您正在执行多表继承。这将创建一个父表 - B 和一个子表 - C。C 将有一个名为 b_ptr_id 的主键,它也是 B.id 的外键。由于 A 包含 B 的外键,这就是你得到的。您可以像这样引用子对象:

b_object = B.objects.get(…)
c_object = b_object.c

但是当然,如​​果从 B 继承了多个表,您将不会不提取哪个子对象。此实用程序可能会对您有所帮助:https ://django-model-utils.readthedocs.org/en/latest/managers.html#inheritancemanager它会满足您的需求。调用.select_subclasses()查询集会自动将每个对象“投射”到它“真正”的任何子对象。

于 2013-09-15T01:42:09.990 回答
0

实际上,在做了更多研究之后,我发现我正在寻找的是“多态”应用程序,在这里找到:https ://github.com/bconstantin/django_polymorphic

于 2014-01-14T01:36:37.313 回答