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
和100kRoom
记录,此查询需要14分钟才能加载。按room\uu gt=0进行筛选时,注释需要5秒钟。此SQL查询忽略在调用extra()
之前应用的filter()
。我需要在单个查询中执行此操作。这意味着您必须使用Django Queryset API,不能使用任何自定义Python代码。您不必添加相关的_名称来访问房间集。默认相关的_名称为“_set”(例如房间_set)。完美!我可以在计算卧室之前使用queryset过滤。