我有两个简单的模型,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)
答案 0 :(得分:2)
由于某些版本的django或python也适用:
A.Objects.all().filter(b__isnull=True)
因为如果a是一个A对象,a.b给出了它存在的子类B
我知道这是一个老问题,但我的回答可能会帮助新的搜索者解决这个问题。
另见:
答案 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)会工作吗?