2011-09-15 11 views
0

モデル持つに設定し、最適なクエリ:Djangoのビュー - のForeignKeyモデル

class Notebook(models.Model): 
    n_id = models.AutoField(primary_key = True) 

class Note(models.Model): 
    b_nbook = models.ForeignKey(Notebook) 

つのパラメータ渡しURLパターン:

(r'^(?P<n_id>\d+)/$', 'notebook_notes') 

をし、次のビュー:

def notebook_notes(request, n_id): 
    nbook = get_object_or_404(Nbook, pk=n_id) 
... 

を次のうち最適なクエリセットはどれですか?その理由は何ですか? (ノートブックで選択されたノートに基づいてノートを作って渡します)

notes = nbook.note_set.filter(b_nbook = n_id) 
notes = Note.objects.select_related().filter(b_nbook = n_id) 

答えて

1

もう少しリンゴとオレンジを比較しています。彼らは事実上同じように戻るかもしれませんが、あなたは両方で異なることをしています。

最初にリレーショナルバージョンを考えてみましょう。そのクエリは、nbookに属するすべてのノートを取得すると言っています。 nbookに属するノートだけでそのクエリーセットをフィルタリングします。実際には同じ基準で2回フィルタリングしています。 Djangoのクエリーセットは怠惰なので、データベースに何回もヒットするなどの悪いことはありませんが、それでもなお必要はありません。

今、2番目のバージョンです。ここでは、すべてのノートから始まり、特定のノートブックに属するものだけにフィルタリングします。今回はフィルタが1つしかありませんが、このようにするのは悪い方法です。それは関係式なので、関係式(例えば、nbook.note_set.all())でそれを調べる必要があります。しかし、このバージョンでは、select_related()も使用していますが、これは他のバージョンでは使用されていません。

select_relatedは、モデル上の他のリレーション(この場合はNote)との結合テーブルの作成を試みます。ただし、Noteの唯一の関係はNotebookであり、すでにノートブックをお持ちの場合は冗長です。あまりにも、他の二つのバージョンとまったく同じ結果を返しますが、非常にクリーンかつ標準化されているだろう、

notes = nbook.note_set.all() 

:これら二つのバージョンでは、すべての冗長性を取り出す

だけが残ります。

+0

詳細な回答ありがとうございます!それはうまく動作し、この場合の最良の方法です。 – barbarosa

関連する問題