如果有子类实例,我如何查询模型?

时间:2009-02-26 13:57:53

标签: python django model-inheritance

我有两个简单的模型,A和B:

from django.db import models

class A(models.Model):
  name = models.CharField(max_length=10)

class B(A):
  age = models.IntegerField()

现在,我如何查询没有B实例的A的所有实例?

我找到的唯一方法是在每个子类上都需要一个显式唯一字段,这是非空的,所以我可以做A.objects.filter(b__this_is_a_b = None),例如,获取不是B实例的实例。我正在寻找一种方法来做到这一点,而不是添加一个明确的愚蠢旗帜。

我也不想查询所有对象,然后在Python中过滤它们。我想让DB为我做这件事,基本上就像SELECT * FROM A WHERE A.id in (SELECT id from B)

3 个答案:

答案 0 :(得分:2)

由于某些版本的django或python也适用:

A.Objects.all().filter(b__isnull=True)

因为如果a是一个A对象,a.b给出了它存在的子类B

我知道这是一个老问题,但我的回答可能会帮助新的搜索者解决这个问题。

另见:

multi table inheritance

我自己的一个问题:downcasting a super class to a sub class

答案 1 :(得分:1)

我不确定是否可以在Django的DB中完全执行此操作 ORM,在单个查询中。这是我能做的最好的事情:

A.objects.exclude(id__in=[r[0] for r in B.objects.values_list("a_ptr_id")])

这是2个DB查询,并且在简单继承时效果最佳 graph - A的每个子类都需要一个新的数据库查询。


好的,它花了很多试验和错误,但我有一个解决方案。它的 像所有地狱一样难看,SQL可能比仅仅更糟糕 两个查询,但你可以这样做:

A.objects.exclude(b__age__isnull=True).exclude(b__age_isnull=False)

在没有引用的情况下,没有办法让Django进行连接 b上的字段。但是通过这些连续的.exclude(),你可以使任何 A 与B子类匹配一个或另一个排除。所有你留下的都是A的 没有B子类。

无论如何,这是一个有趣的用例,你应该在django-dev上提起......

答案 2 :(得分:0)

我不使用django,但看起来你想要isinstance(obj,type)内置的python方法。

修改
A.objects.exclude(id__exact = B__id)会工作吗?