order_with_respect_to用于反向关系

时间:2015-03-13 15:31:00

标签: django django-models

假设我有以下型号:

class Playlist(models.Model):
    name = models.TextField()    
    songs = models.ManyToManyField(Song)

class Song(models.Model):
    title = models.TextField()

因此,播放列表可以包含多首歌曲,并且一首歌曲可以位于多个播放列表中。

我想添加“订单”字段,以便用户可以重新排列播放列表中的歌曲。我找到了order_with_respect_to,这似乎是一个完美的解决方案。但是,我需要将{meta}选项添加到Song模型中,例如:

class Song(models.Model):
    title = models.TextField()

    class Meta:
        order_with_respect_to = 'playlists'

显然,由于我已经获得了播放列表模型中指定的关系,因此在Song上没有指定播放列表字段。有没有办法使用order_with_respect_to指定related_name的反向关系?或者我可以在歌曲模型中拍一个ForeignKey对播放列表的引用吗?

1 个答案:

答案 0 :(得分:1)

当您拥有order_with_respect_to而非ForeignKey时,

ManyToManyField(可以说)非常有用。它的工作原理是在模型中添加一个额外的字段,但在您的情况下,订单会因Playlist而异。

在Django中执行此操作的直接方法是将订单放在显式创建的through表中。

class Playlist(models.Model): 
    name = models.TextField()
    songs = models.ManyToManyField(Song, through='PlaylistSong')

class Song(models.Model):
    title = models.TextField()

class PlaylistSong(models.Model):
    playlist = models.ForeignKey(Playlist)
    song = models.ForeignKey(Song)
    order = models.PositiveSmallIntegerField()

因此,要按照正确的顺序获取Songs中的Playlist,您可以执行以下操作:

Song.objects.filter(playlistsong__playlist_id=1)
            .order_by('playlistsong__order')