2011-02-10 27 views
6

Djangoモデルを使用して2つ(またはそれ以上)の結合テーブルで選択を行うにはどうすればよいですか?例えばDjangoモデルと2つ以上のテーブルを結合したSELECT?

class Album(models.Model): 
    artist = models.ForeignKey(Musician) 
    name = models.CharField(max_length=100) 
    release_date = models.DateField() 
    num_stars = models.IntegerField() 

class Song(models.Model): 
    album = models.ForeignKey(Album) 
    name = models.CharField(max_length=100) 
    num_stars = models.IntegerField() 

SELECT * from album, song where (album.id = song.album_id) and (album.artist_id = X) 
+0

私はあなたのデータベースの内容を求めていませんでしたが、あなたのモデル(またはデータベーススキーマ)とあなたが実行したいと思うSQL。 – gruszczy

+0

私はもう一度編集しました:) –

答えて

13

Djangoクエリーセットは、単一の結果テーブルに結合された複数のテーブルからデータを返すSQLの概念にはあまり対応していないモデルインスタンスのリストを返したいとします。

あなたは一例として提供するSQLクエリの効果を達成するには、次のいずれかを実行できます。

1)あなたは曲によってあなたのデータを反復処理したい場合は、照会の曲を制限することができますそのようなアーティストIDによって:

songs = Song.objects.filter(album__artist__id=123) 
for song in songs: 
    print song.name 
    print song.album.name 
    ... do what ever you need to do with song here ... 

パフォーマンスを懸念している場合、あなたはあなたのクエリセットにselect_related()を追加することができます。あなたはアルバムであなたのデータを反復処理したい場合は

# the depth argument tells django to only follow foreign key relationships 
# from Song one level deep 
songs = Song.objects.select_related(depth=1).filter(album__artist__id=123) 

for song in songs: 
    # django has now already fetched the album data, so accessing it 
    # from the song instance does not cause an additional database hit 
    print song.album.name 

2)、あなたはそうのようなものを行うことができます。

albums = Album.objects.filter(artist__id = 123) 
for album in albums: 
    for song in album.song_set.all(): 
     print song.name 
     print album.name 
     ... etc ... 
+0

これは、最適化したい場合、select_related()で例1を使用する方が良いでしょうか?他のすべてのケースでは1つ以上の選択を使用しますか? –

+0

@ju - select_related()はforeign_key関係に従うように作成されているため、Album.objectsを介して関連する曲を1つのクエリでプリフェッチするのは簡単ではありません。だから、はい、select_related()を使用した例1は、おそらくデータベースクエリを最小限に抑えたい場合に行く方法だろうと思います。 – zlovelady

0

あなたはraw sql queryを行うことができますが、それはおそらくあなたがやりたいことではありません。どのようにあなたのモデルがどのように見えるか、あなたが達成したいと思うもの、そしておそらくdjango ORMがクエリを実行するのに十分であることを説明してください。

+0

私の質問を編集しました。例: –

関連する問題