Python Django ORM:统计具有特征的相关对象

Python Django ORM:统计具有特征的相关对象,python,django,aggregate,django-queryset,Python,Django,Aggregate,Django Queryset,假设我们有房子和房间模型每间房子都有几间房间,每间房间都有几张床 如何选择每间房屋的卧室数量?所有房屋必须出现在结果中 模型类: class House(models.Model): pass class Room(models.Model): house = models.ForeignKey('House') beds = models.IntegerField() 我试过: House.objects.filter(room__beds__gt=0).annot

假设我们有房子房间模型
每间房子都有几间房间,每间房间都有几张

如何选择每间房屋的卧室数量?所有房屋必须出现在结果中

模型类:

class House(models.Model):
    pass

class Room(models.Model):
    house = models.ForeignKey('House')
    beds = models.IntegerField()
我试过:

House.objects.filter(room__beds__gt=0).annotate(bedrooms=Count('room'))
但是这个解决方案不包括没有卧室的房子

我不喜欢使用纯SQL。

试试看

House.objects.extra(select={
        "bedrooms": "SELECT count(*) FROM YOURAPP_room WHERE house_id=YOURAPP_house.id AND beds > 0"})

相关的\u名称
添加到房间类中的“您的房子”字段中。它将如下所示:

house = models.ForeignKey('House', related_name='rooms')
from itertools import chain
from django.db.models import Q, Count

qs = House.objects.all()
q = {'room__beds__gt': 0}
qs_with = qs.filter(Q(**q)).annotate(bedrooms=Count('room'))
qs_without = qs.filter(~Q(**q)).extra(select={'bedrooms': 0})
qs_all = chain(qs_with, qs_without)
然后,您可以从
House
对象访问
Room
对象

现在,如果
h1
House
的对象,您可以这样做

rooms_total = 0

for room in h1.rooms.all():
  rooms_total += room.beds

您可以将没有卧室的房屋添加到查询中,如下所示:

house = models.ForeignKey('House', related_name='rooms')
from itertools import chain
from django.db.models import Q, Count

qs = House.objects.all()
q = {'room__beds__gt': 0}
qs_with = qs.filter(Q(**q)).annotate(bedrooms=Count('room'))
qs_without = qs.filter(~Q(**q)).extra(select={'bedrooms': 0})
qs_all = chain(qs_with, qs_without)

我不喜欢使用纯SQL。还有其他建议吗?我认为在没有SQL的情况下,这在单个查询中是行不通的。这个解决方案实际上是不可用的。对于1k
House
和100k
Room
记录,此查询需要14分钟才能加载。按
room\uu gt=0进行筛选时,注释需要5秒钟。此SQL查询忽略在调用
extra()
之前应用的
filter()
。我需要在单个查询中执行此操作。这意味着您必须使用Django Queryset API,不能使用任何自定义Python代码。您不必添加相关的_名称来访问房间集。默认相关的_名称为“_set”(例如房间_set)。完美!我可以在计算卧室之前使用queryset过滤。