如何在Django中查询反向外键属性?



我们正在使用Django 1.4.12和PostgreSQL来建立一个酒店网站。我们有酒店,每个酒店都有房间,每个房间都有客人(客人有房间的外钥匙,房间有酒店的外钥匙)。客人从房间退房后,他的departure_date设置为now,如果他在房间里,则为none。我想选择有客人的房间和没有客人的房间,但是我不能使用"guests__isnull",因为客人在退房后仍然与房间保持连接。我还需要搜索房间时,客人的名字包含一个关键字,但只有当他们在房间里。如果房间中至少有一位客人具有匹配的名称,我希望选择该房间。但是如果这位客人退房了,房间就不能选了。

直到几天前,我们在客人退房后搬走了他们的房间,但我们需要保留它来保存历史。我们的代码是这样的:

hotel.rooms.filter(
    Q(description__icontains=keyword) | 
    Q(identifier__icontains=keyword) | 
    (Q(guests__isnull=False) & Q(guests__name__icontains=keyword))
).distinct()

和入住的房间,我们增加了.exclude(guests__isnull=True)。但是现在我们保留房间,我们需要检查departure_date是否为空。我们现在怎么做呢?请记住,我们需要将关键字与房间内的客人匹配,而不是与不在房间内的客人匹配。我们还需要计算有客人的房间总数和没有客人的房间总数。

更新:我试图用以下查询来计算有客人的房间数量:

hotel.rooms.filter(guests__isnull=False, guests__departure_date__isnull=True).count()

但是它返回一个不正确的数字(14而不是10)。你知道如何修复这个查询吗?

顺便说一下,这个查询返回没有客人的正确房间数(9个房间):

hotel.rooms.exclude(guests__isnull=False, guests__departure_date__isnull=True).count()

为什么排除正确而过滤器不正确?

好的,我找到了一个解决方案。似乎使用filter(…),房间会根据房间内的客人数量被复制,但使用exclude则不会。有两种可能的解决方案来计算有客人的房间数量:

hotel.rooms.filter(guests__isnull=False, guests__departure_date__isnull=True).distinct().count()

或:

hotel.rooms.exclude(~Q(guests__isnull=False, guests__departure_date__isnull=True)).distinct().count()

计算没有客人的房间数:

hotel.rooms.exclude(guests__isnull=False, guests__departure_date__isnull=True).distinct().count()

或:

hotel.rooms.exclude(Q(guests__isnull=False, guests__departure_date__isnull=True)).distinct().count()

和搜索房间:

hotel.rooms.filter(
    Q(description__icontains=keyword) |
    Q(identifier__icontains=keyword) |
    Q(guests__isnull=False, guests__departure_date__isnull=True, guests__name__icontains=keyword)
).distinct()

相关内容

  • 没有找到相关文章

最新更新