2009-10-23 14 views
5

私は単純な音楽スキーマを持っています:Artist、Release、Track、Song。最初の3曲はすべて論理的な構成ですが、4曲目はmp3、wav、oggのような(アーティスト、リリース、トラック)の特定のインスタンスです。Django ORM - select_relatedとorder_by foreign keys

データベース内のソングの順序付きリストを生成できません。キャッチは、TrackReleaseの両方がArtistであることです。 Song.Track.Artistは常に出演者名ですが、Song.Track.Release.Artistは演奏者名または編集のための "Various Artists"です。私はどちらかとして並べ替えることができるようにしたい、そして私はこの仕事をする正しい方法を理解することができません。

は、ここに私のスキーマです:

class Artist(models.Model): 
    name = models.CharField(max_length=512) 

class Release(models.Model): 
    name = models.CharField(max_length=512) 
    artist = models.ForeignKey(Artist) 

class Track(models.Model): 
    name = models.CharField(max_length=512) 
    track_number = models.IntegerField('Position of the track on its release') 
    length = models.IntegerField('Length of the song in seconds') 
    artist = models.ForeignKey(Artist) 
    release = models.ForeignKey(Release) 

class Song(models.Model): 
    bitrate = models.IntegerField('Bitrate of the song in kbps') 
    location = models.CharField('Permanent storage location of the file', max_length=1024) 
    owner = models.ForeignKey(User) 
    track = models.ForeignKey(Track) 

私のクエリはかなり単純でなければなりません。特定のユーザーが所有するすべての曲をフィルタリングし、Song.Track.Artist.nameまたはSong.Track.Release.Artist.nameのいずれかで並べ替えます。ここでSong.Track.Artist.nameによってソートされたビュー、内部の私のコードは次のとおりです。

songs = Song.objects.filter(owner=request.user).select_related('track__artist', 'track__release', 'track__release__artist').order_by('player_artist.name') 

私はtblname.colnameを使用しない限り、私はorder_byを動作させることはできません。私は基礎となるクエリオブジェクトのas_sqlメソッドを調べました。内部結合が行われたときにT6がテーブルのために使用されていることを示します。Song.Track.Artist

>>> songs = Song.objects.filter(owner=request.user).select_related('track__artist', 'track__release', 'track__release__artist').order_by('T6.name') 
>>> print songs.query.as_sql() 
('SELECT "player_song"."id", "player_song"."bitrate", "player_song"."location", 
    "player_song"."owner_id", "player_song"."track_id", "player_track"."id", 
    "player_track"."name", "player_track"."track_number", "player_track"."length", 
    "player_track"."artist_id", "player_track"."release_id", "player_artist"."id", 
    "player_artist"."name", "player_release"."id", "player_release"."name", 
    "player_release"."artist_id", T6."id", T6."name" FROM "player_song" INNER JOIN 
    "player_track" ON ("player_song"."track_id" = "player_track"."id") INNER JOIN 
    "player_artist" ON ("player_track"."artist_id" = "player_artist"."id") INNER JOIN 
    "player_release" ON ("player_track"."release_id" = "player_release"."id") INNER JOIN 
    "player_artist" T6 ON ("player_release"."artist_id" = T6."id") WHERE 
    "player_song"."owner_id" = %s ORDER BY T6.name ASC', (1,)) 

これをテーブル名としてorder_byに入力すると(上記の出力例を参照)、これは完全に移植できないようです。確かにこれを行う良い方法があります!私は何が欠けていますか?

答えて

24

私は本当にあなたの質問が何であるか理解できません。

訂正:select_relatedは、注文とは関係ありません(クエリーセットはまったく変更されません。関連するオブジェクトを取得してキャッシュするためにジョインするだけです)。関連するモデルのフィールドで注文するには、ダブルアンダースコア表記を使用します。ドット区切りは使用しません。たとえば、次のように

Song.objects.filter(owner=request.user).order_by('track__artist__name') 

しかし、あなたの例では、あなたはどこでもあなたのモデル内のフィールドではないようです「player_artist」を使用します。私はあなたのポータビリティへの言及を理解していません。

関連する問題