【问题标题】:Python Django: Filter within for loopsPython Django:在 for 循环中过滤
【发布时间】:2020-12-04 03:02:51
【问题描述】:

上下文

我目前在我的数据库中存储了“Building”和“Room”对象 - 由外键链接。

我正在尝试使用 for 循环和 objects.filter() 为每个 Building 生成 Room 查询集

问题

请参阅下面发布的代码 - 我似乎无法解决一个看似简单的问题。

'BuildingList' 返回两个对象,但由于某种原因,我的 for 循环仅查询并为两个建筑物之一附加一个“RoomList”。 (第二个)

我不明白为什么,但是 RoomList = Room_Data.objects.filter(Room_Building=b) 似乎破坏了我基本 for 循环的逻辑和流程。


Python 脚本:

#
#
# 1.) GET DATA FOR RELEVANT SET OF BUILDINGS

FusionBuildingName = "Renal Dialysis Unit x6"

BuildingRoomLists = []



# GET DATA FOR ALL BUILDINGS MATCHING 'FusionBuildingName'
BuildingList = Building_Data.objects.filter(Building_Name=FusionBuildingName)

print(len(BuildingList))
print(BuildingList)


# GENERATE BUILDING ROOM LISTS
for b in BuildingList:
    
    print(b)
    print("Building Author: " + b.Building_Author)
    
    print("Building Room List:")
    
    # GET LIST OF ROOM OBJECTS FOR CURRENT BUILDING
    RoomList = Room_Data.objects.filter(Room_Building=b)
    
    print(str(RoomList))
    
    # APPEND LIST OF ROOM OBJECTS TO BUILDING ROOM LIST
    BuildingRoomLists.append(RoomList)
    

以下是我的 Python Shell 在运行上述代码时返回的内容:

In [43]:
In [44]:     ...:     ...:     ...:     ...:     ...:     ...:     ...: Building_Data object (1)
1
Building Author : Angel Mahchut
Building_Data object (2)
2
Building Author : AusHFG

In [45]: Building Room List:

In [46]:
In [46]:
In [46]:
In [47]:
In [48]:
In [48]:
In [48]: <QuerySet [<Room_Data: Room_Data object (41)>, <Room_Data: Room_Data object (42)>, <Room_Data: Room_Data object (43)>, <Room_Data: Room_Data object (44)>, <Room_Data: Room_Data object (45)>, <Room_Data: Room_Data object (46)>, <Room_Data: Room_Data object (47)>, <Room_Data: Room_Data object (48)>, <Room_Data: Room_Data object (49)>, <Room_Data: Room_Data object (50)>, <Room_Data: Room_Data object (51)>, <Room_Data: Room_Data object (52)>, <Room_Data: Room_Data object (53)>, <Room_Data: Room_Data object (54)>, <Room_Data: Room_Data object (55)>, <Room_Data: Room_Data object (56)>, <Room_Data: Room_Data object (57)>]>

In [49]:
In [49]:
In [50]:

尽管循环遍历 2 个建筑对象,但“Building Room List:”和“

非常感谢任何帮助。我已经在这个问题上停留了一段时间......

【问题讨论】:

  • Room_Data.Room_Building 是 Building_Data 的外键字段吗? 2个模型类之间的关系是什么?
  • 是的,我已将其设置为一对(建筑物)对多(房间)关系,并在 Room_Data 模型类中使用以下行:Room_Building = models.ForeignKey(Building_Data, on_delete=models.CASCADE)

标签: python django for-loop filter


【解决方案1】:

您将整个queryset 附加到数组中,因此您会发现queryset 作为数组的单个元素。如果您尝试创建查询集的对象列表...您可以简单地使用 list() 将其设为数组。

例如:

BuildingRoomLists = []
FusionBuildingName = "Renal Dialysis Unit x6"

BuildingList = Building_Data.objects.filter(Building_Name=FusionBuildingName)

for b in BuildingList:
    RoomList = Room_Data.objects.filter(Room_Building=b)
    RoomList = list(RoomList)
    BuildingRoomLists += RoomList)

这样就可以了……

【讨论】:

  • 感谢您的回复 - 尽管我的循环仍然有问题。有两座建筑物,所以“for b in BuildingList”应该为它们生成一个“RoomList”。由于某种原因,循环只会为两个建筑物中的第二个生成查询集。我的最终数组应该是:[ [ Room 1.1, Room 1.2... x40 Rooms], [ Room 2.1, Room 2.2... x 17 Rooms] ]。相反,它只是:[ [ 房间 2.1,房间 2.2... x 17 房间] ]。我不明白为什么没有生成第一个建筑物房间查询集。
【解决方案2】:

Building_Data 和 Room_Data 两个模型之间的关系尚不清楚,因为您在问题中没有提到这一点,但如果 Room_Data.Room_Building 是 Building_Data 的外键并且您只想检索所有房间满足特定条件的建筑物(在您的情况下为Building_Name=FusionBuildingName),您可以简单地在filter() 中使用fieldname__in 查找,而不是遍历每个Building_Data 实例。

[更新] 修正代码中的错字

快速示例:

# retrieve list of buildings instances (represented as QuerySet) with specific naming pattern ....
BuildingList = Building_Data.objects.filter(Building_Name=FusionBuildingName)
# find out all rooms associated with the given list of buildings,
RoomList = Room_Data.objects.filter(Room_Building__in=BuildingList)
# convert (from QuerySet) to list, start database access
BuildingRoomLists = list(RoomList)

上面的例子可以减少你的代码实现也减少数据库访问次数,因为queryset is lazy。

【讨论】:

  • 谢谢,这可能会导致潜在的解决方法。我现在需要做的就是将房间列表拆分为每个建筑物的单独列表。我希望用我的循环来解决最初的问题 - 我在我的代码中多次遇到同样的问题,但这暂时可以:-)
【解决方案3】:

我通过对以下代码行的小幅更新解决了我的问题:

RoomList = Room_Data.objects.filter(Room_Building=b)

到

RoomList = Room_Data.objects.filter(Room_Building=BuildingList[BuildingList.index(b)])

现在我可以成功地为每个“Building_Data”生成独立的“Room_Data”对象查询集,而不会导致循环失败 - 尽管我不完全确定为什么需要进行此更改。

【讨论】:

    猜你喜欢
    • 2011-10-12
    • 2017-04-21
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    相关资源
    最近更新 更多