2014-04-04 33 views
0

Django文檔不太清楚如何過濾對象,使它們包含相關字段的過濾子集。Django模型與相關字段的過濾子集

假設我有以下型號:

class Device(models.Model): 
    name = models.CharField(max_length=50) 

class DeviceEvent(models.model): 
    device=models.ForeignKey(Device, null=False, related_name='device_events') 
    handled = models.BooleanField(default=Fasle) 

現在假設我希望檢索有未處理的DeviceEvents所有設備的列表。我如何在Django中編寫查詢來做到這一點?

最終結果應該是設備,其中devices是Device對象的列表,並且對於每個設備對象「device」,我們有device.device_events是未處理的DeviceEvent對象的列表。這可能在Django中做到嗎?

或者,我可以做到這一點在Python這樣的:

all_devices=Device.objects.all() 
devices=[] 
for thedevice in all_devices: 
    unhandled_device_events=thedevice.device_events.\ 
             annotate(num_events=Count('device_events')).\ 
             filter(device_event__device=thedevice).\ 
             filter(num_events__gt=0).\ 
             filter(device_event__handled=False).all() 
    if unhandled_device_events: 
     thedevice.device_events=unhandled_device_events 
     devices.append(thedevice) 

在上面,我創建了一個名爲設備的新列表,然後通過所有設備對象循環和手動添加設備到設備,只有當它至少有一個未處理的事件,並且該設備對象現在具有device.device_events =未處理的設備事件(不是所有設備事件)。這是允許的還是高效的?

或者當我將其中一個device_events稱爲「device_event」而不是「deviceevent」時,它是正確的?

回答

0

如果我理解正確你的問題,我認爲這應該工作

Device.objects.get(Device.device_events.handled = False) 
+0

沒有,返回一個設備對象,而進去的語法看起來是錯誤的。 – Marc

+0

你確定嗎?你有沒有測試過它?爲什麼裏面的代碼看起來錯了? :) –

0

因爲它是一個ForeignKey關係,我相信你可以抓住時都興奮到設備與此(假設d的DeviceEvents的是一個實例設備類的):

d.deviceevent_set.all() 

你應該能夠過濾掉,像這樣:

d.deviceevent_set.filter(handled=False) 

我沒有測試過這個,但我認爲它會工作。

編輯:在閱讀您的評論後,我意識到我沒有像我想象的那樣仔細閱讀您的問題。

在拔出所需設備後,您可以在for循環中使用上面的代碼。獲取設備實例,然後使用此代碼段獲取與該設備關聯的未處理事件。例如,遍歷device.objects.all()中的所有內容並檢查d.device_set.filter(handled = false)是否爲每個設備返回任何內容。如果是,則可以將該設備作爲關鍵字添加到字典中,並將未處理的事件列表作爲關聯值添加到字典中。你將得到一個設備字典[unhandledevents]。如果你想的話,This post可以告訴你更多關於這個的信息。

您能否以您需要的方式操縱數據,或者我是否根據您的要求來操作數據?

+0

是的,但我想所有的設備不是所有的設備事件 – Marc

0

試試這個

d = Device.objects.filter(device_events__handled=False)