2013-07-30 86 views
0

我簡直難倒了。我試圖在我的django應用程序中實現一個prefect_related的教科書案例,但它不起作用。以下是相關機型:prefetch_related不緩存

class CanUseUnit(models.Model): 

    objects = UnitManager() 

    ingredient = models.ForeignKey('Ingredient', db_column='ingredient', related_name='useable_units') 
    unit = models.ForeignKey('Unit', related_name='used_by', db_column='unit', limit_choices_to=models.Q(parent_unit__exact=None)) 

請注意,雖然這種模式有一個自定義的經理,這是models.Managar只有1名爲get_all_info()方法簡單的子類,所以我不認爲這有什麼用我的問題:

我想查詢所有成分,並預取它們的可用單位。這是我的Django的查詢:

def list_ingredients(request): 
    ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('useable_units') 
    for ingredient in ingredients: 
    print(ingredient.useable_units.all()) 

    return render(request, 'admin/list_ingredients.html', {'ingredients': ingredients}) 

但Django的似乎打在每個print語句從數據庫...到底是怎麼回事?

編輯:

似乎從模板調用時,緩存工作。當我離開了print語句按上述觀點來看,並訪問該頁面包含以下模板代碼:

{% for ingredient in ingredients %} 
<tr> 
    <td><a href="/ingredients/edit/{{ ingredient.id }}/">{{ ingredient.name }}</a></td> 
    <td align="center">{{ ingredient.useable_units.count }}</td> 
</tr> 

{% endfor %} 

該數據庫只擊中兩次(這是我所期望的,曾經爲原料,並曾經爲prefetch_related )。

求助: 好了,問題似乎已經解決了......我一直試圖重新啓動測試服務器,並突然停止查詢每個成分。不知道發生了什麼,但我很高興解決了。

回答

0

我發現了這個問題。 Schacki的回答是錯誤的,與預取有關的確實只需要2個查詢,而不是每個成分一個。

我的錯誤是在模板,其中我被顯示所述中間模型的屬性的不同部分。

那麼我應該做的是以下內容:

ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('canuseunit_set') 

代替:

ingredients = Ingredient.objects.all().order_by('accepted', 'name').prefetch_related('useable_units') 
-2

如果你看一下文檔:https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related,它說,

prefetch_related,而另一方面,不存在於每一關係的單獨的查詢,並且確實在Python

的「加盟」

從我的理解,這正是你所看到的。

+0

好吧,我發現了一個以前的SO問題,其中從接受的答案,我帶領相信它只會做2個查詢(不是每個成分1):[鏈接](http://stackoverflow.com/questions/11746229/django-left-join-efficiently)但如果不是這種情況,是否沒有方式來做批量prefetch_related? – Gargamel

+0

似乎有一個誤解,關係是ForeignKey關係,所以「對於每個關係」意味着每個ForeignKey,OneToOne,ManyToMany等等。所以是的,在你的情況下只有2個,但是他發佈的內容也是正確的。它並不回答你的問題,但也不是事實錯誤。 – CrazyCasta