我有一个像这样的数据库架构:
class Family(models.Model):
pass
class Child(models.Model):
family = models.ForeignKey(Family)
name = models.TextField()
age = models.IntegerField()
gender = models.CharField(max_length=1)
我想要一个查询,返回有5岁以下男孩的家庭中的所有孩子。
我该如何表达?我得到的最近的是:
# WRONG: this is no good, it will only return boys under 5, but I want all
# children in families with boys under 5.
Child.objects.filter(gender='M', age__lt=5)
# WRONG: this is no good, it is closer but will also return children in
# families with a 6yo boy and a 3yo girl.
Child.objects.filter(family__child__gender='M', family__child__age__lt=5)
答案 0 :(得分:1)
你说你想要所有男孩在5岁以下男孩的家庭 这是一个很大的暧昧,但我会假设你想要的家庭至少包含一个不到5岁的男孩
这样可行:
families = Family.objects.filter(child__gender='M', child__age__lt=5).prefetch_related('child')
然后你可以迭代家庭对象来检索他们各自的孩子
答案 1 :(得分:1)
获取有5岁以下男孩的id
的{{1}},然后在这些Family
上过滤Child
。以下查询仅对数据库命中一次:
id
答案 2 :(得分:1)
您可以尝试__in
- 这样的查询:
boys_under_5 = Child.objects.filter(gender='M', age__lg=5)
Child.objects.filter(family__child__in=boys_unter_5)
至于为什么你的原始查询不起作用,我建议阅读generared SQL:
print Child.objects.filter(family__child__gender='M', family__child__age__lt=5).query
答案 3 :(得分:0)
正如@knbk在评论中指出的那样,当我写这个问题时,我确实错了。我假设一个不存在的默认行为。那么,最好的答案是我给出的答案:
Child.objects.filter(family__child__gender='M', family__child__age__lt=5)
如果你想要找回有一个男孩和一个(可能是不同的)5岁以下孩子的家庭中的所有孩子,你必须这样做:
Child.objects.filter(family__child__gender='M').filter(family__child__age__lt=5)
这里提供的文档链接@knbk详细介绍了该功能:https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships
如果他回答,我会将积分转移给他。