2013-05-14 44 views
0

我得到了父子(1-n)模型關係:如何過濾後得到的單相關對象

class Parent(models.Model): 
    some_fields = models.IntegerField() 

class Child(models.Model): 
    parent = models.ForeignKey(Parent, relatend_name='children') 
    first = models.BooleanField() 
    second = models.BooleanField() 

現在我根據兒童的字段篩選的父母:

Parent.objects.filter(children__first=True) 

這將產生下面的SQL:

SELECT app_parent.* 
FROM app_parent 
INNER JOIN app_child ON app_parent.id = app_child.parent_id 
WHERE app_child.first = TRUE 

後,我得到了所有父領域我想相關的子領域也得到SQL這樣的:

SELECT app_parent.*, app_child.* 
FROM app_parent 
INNER JOIN app_child ON app_parent.id = app_child.parent_id 
WHERE app_child.first = TRUE 

,並通過Django的ORM得到它。有任何想法嗎?

UPDATE

我想我有很好的解決辦法

parents = Parent.objects.filter(children__first=True).prefetch_related('children') \ 
.extra(select={'child_id': '"app_child"."id"'}) 
for parent in parents: 
    parent.child = [child for child in parent.children.all() if child == parent.child_id][0] 
+0

看看'for'循環。從預取的孩子列表中篩選出第一個孩子的孩子屬性。 – ArturM 2014-01-27 10:34:29

回答

1

您可以使用prefetch_related

Parent.objects.filter(children__first=True).prefetch_related('children') 

或者select_related

Child.objects.filter(first=True).select_related('parent') 
+0

我只想要一個孩子與第一=真 – ArturM 2013-05-14 13:27:19

+0

如果對於每個父母,那裏是'first'爲true的多個子元素,那麼您只能隨機選擇返回的queryset中的第一行,您可以使用'Parent.objects.filter(children__first = True)[0]' – 2013-05-14 13:31:22

+0

@ArturM我加了'select_related'信息讓一個孩子回來,但那個評論帶來了一個好點... – Ngenator 2013-05-14 13:33:29

0

你必須使用該fetch_related方法並執行查找周圍的其他方法很遺憾。

在這種情況下,它應該是這樣的:

first_children = Child.objects.filter(first=True).select_related('parent') 
parents = [c.parent for c in first_children] 
+0

我使用這個Python解決方案atm(順便說一句,我認爲它應該是select_related) – ArturM 2013-05-14 13:31:18

+0

是的......我得到它與prefetch_related,你是對的困惑:) – Wolph 2013-05-15 00:03:24

相關問題