2011-02-10 2 views
6

Django 모델을 사용하여 두 개 이상의 조인 된 테이블을 선택하려면 어떻게해야합니까? 예를 들어Django 모델과 두 개 이상의 테이블을 조인 한 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

장고 쿼리 세트는 단일 인스턴스 결과 테이블에 조인 된 여러 테이블의 데이터를 반환한다는 SQL 개념과 완전히 일치하지 않는 모델 인스턴스 목록을 반환하려고합니다. 당신이 노래하여 데이터를 반복하려면

1), 당신은 당신이 쿼리 노래를 제한 할 수 있습니다

, 당신은 다음 중 하나를 수행 할 수 있습니다 당신이 예제로 제공하는 SQL 쿼리의 효과를 달성하기 위해 그래서 같은 아티스트 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를 통해 관련 노래를 프리 페치 (fetch)하는 쉬운 방법은 하나의 쿼리로만 표시됩니다. 예, select_related()를 사용하는 예제 1은 데이터베이스 질의를 최소화하려는 경우 아마도 갈 방법이 될 것입니다. – zlovelady

0

당신은 raw sql query을 수행 할 수 있지만, 아마 당신이 원하는 것은 아니다. 귀하의 모델이 어떻게 생겼는지, 달성하고자하는 것을 설명하십시오. 아마도 장고 ORM만으로도 쿼리를 수행 할 수 있습니다.

+0

예제와 함께 제 질문을 편집했습니다. –

관련 문제