2012-02-25 67 views
2

我有兩個型號:打電話給他們的問題和答案:避免n + 1查詢查詢模型加上所有ForeignKey關聯?

class FacetQuestion(models.Model): 
    the_question = models.CharField(max_length=50) 

class FacetAnswer(models.Model): 
    question  = models.ForeignKey(FacetQuestion) 
    display_order = models.SmallIntegerField() 
    the_answer  = models.CharField(max_length=1024) 

我想提出的所有問題和答案在一個列表,每個我選擇訂購的問題和答案:

Q1 
    A1 
    A2 
    A3 
Q2 
    A10 
    A9 
    A4 

沒有創建n + 1數據庫查詢或創建愚蠢的外觀模板。 這是一個很容易加入像我這樣的一個數據庫的傢伙,但託託告訴我們,我們是不是在SQL土地了:

select title_short,answer_note from coat_facetquestion 
join coat_facetanswer on (coat_facetanswer.question_id=coat_facetquestion.id) 
order by coat_facetquestion.id,coat_facetanswer.display_order; 

什麼是在Django的最佳方法,並且將模板是什麼樣子?

<ul> 
    {% for q in questions %} 
    <li>{{ q.the_question }}</li> 
     {% for a in q.FacetAnswers_set.all %} 
      <li>{{ q.the_answer }}</li> 
     {% endfor %} 
    {% endfor %} 
</ul> 

我看到一個較老的模塊,在django-batch-select有點正軌。還有select_related()這感覺就像它一定是答案,但如果是這樣的話,文檔沒有那麼清楚。

回答

0

基於搜索其他堆棧交換答案:用於處理分層數據,最好的似乎是http://django-mptt.github.com/django-mptt/

對於簡單地減少查詢數select_related()是一個很大的幫助。

用於顯示分級結果我還沒有找到太多。

0

我只能回答你問題的一部分。

select_related()可能不是你要找的。它會選擇你1:n關係的「單面」。這將允許您選擇所有答案,並且一次性爲每個答案提取相關問題。

然而,你可以使用相關實體的屬性這樣的過濾查詢:

FacetAnswer.objects.filter(question__property = 'some_value').select_related() 

而且,你的查詢集將基於應答的模式,所以你只能迭代for a in answers

1

您可以使用FacetQuestion.objects.select_related('facetanswer_set').all()

也有看setdefault()。這是一個Python命令,可以讓你建立一個嵌套的字典結構。您查詢所有問題和所有答案,然後使用Python構建您需要的結構。

+0

select_related()幫助,認爲這不是完整的解決方案。謝謝。 – Bryce 2012-03-01 06:41:00