2012-02-28 103 views
0

我有這兩款車型Django的許多一對多查詢滿足特定條件

class Genre(TimeStampAwareModel): 
    genre = models.CharField (max_length = 255, blank = False) 
    parent = models.ForeignKey ('self', null=True, blank=True, related_name = "childs") 
    .. 
class Track(TimeStampAwareModel): 
    .... 
    genre = models.ManyToManyField(Genre) 

我作爲流派的輸入列表[流行,搖滾,..],因爲流行音樂和搖滾有孩子太流派。現在我想篩選所有曲目滿足以下條件

(G1parent OR G1child1或G1child2 OR .....)AND(G2parent或G2child1或G2child2 OR .....)

def get_genre_tracks(list_genre): 
    .... 
    ... 
    return tracks 

這裏G1parent是Pop和G2parent是Rock,我怎麼得到這個?尋找一個優雅的解決方案。

謝謝!

回答

4

如果我理解你的話,你希望所有的曲目有「搖滾」這個以「搖滾」爲父項的曲風。如果是這樣的:

from django.db.models import Q 

Track.objects.filter(Q(genre__genre='Rock') | Q(genre__parent__genre='Rock')).distinct() 

編輯

事實上,經過重新閱讀,似乎這個問題你要我說什麼,但對於流派的名單一起,而不是僅僅一次一個。對於這一點,你只需要調整上面的代碼,如:

Track.objects.filter(Q(genre__genre__in=['Rock', 'Pop']) | Q(genre__parent__genre__in=['Rock', 'Pop'])).distinct() 

UPDATE

啊,那麼這是一個比較複雜一點,但仍是可行的。

has_rock_genres = Q(genre__genre='Rock') | Q(genre__parent__genre='Rock') 
has_pop_genres = Q(genre__genre='Pop') | Q(genre__parent__genre='Pop') 

Track.objects.filter(has_rock_genres & has_pop_genres).distinct() 

你可以在一行中完成所有操作,但代碼在這一點上會變得有點混亂。

UPDATE

真的給了我一個鍛鍊的心理今天,不是嗎? ;)

你需要做這樣的事情:

query = None 
for genre in genres: 
    if query is None: 
     query = Q(genre__genre=genre) | Q(genre__parent__genre=genre) 
    else: 
     query = query & (Q(genre__genre=genre) | Q(genre__parent__genre=genre)) 

    Track.objects.filter(query).distinct() 
+0

不,我想,有岩石或它的子類型和POP或子類型的所有曲目?希望你明白我的問題 – Ahsan 2012-02-28 15:52:23

+0

'genre__genre__in = ['Rock','Pop']'會得到所有曲目有Rock或Pop,但我想AND AND – Ahsan 2012-02-28 15:58:17

+0

我想要確切的在你最後的編輯,但我有父母名單流派。我怎麼能在一行中做到這一點? – Ahsan 2012-02-28 16:19:54