Django:根据条件对外键进行分组和排序

时间:2012-04-16 20:38:07

标签: python sql django

我有一些Django模型记录了人们的听音习惯(有点像Last.fm),如下所示:

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

class Song(models.Model):
    artist = models.ForeignKey(Artist)
    title = models.CharField()

class SongPlay(models.Model):
    song = models.ForeignKey(Song)
    user = models.ForeignKey(User)
    time = models.DateTimeField()

class User(models.Model):
    # doesn't really matter!

我希望有一个用户页面,我可以在其中显示过去一个月他们收听过的热门歌曲。最好的方法是什么?

到目前为止,我提出的最好的是:

SongPlay.past_month
    .filter(user=user)
    .values('song__title', 'song__id', 'song__artist__name')
    .annotate(plays=Count('song'))
    .order_by('-plays')[:20]

上面,past_month是一名经理,仅过滤上个月的比赛。假设我们已经有了正确的user对象来过滤。

我想我的两个问题是:

  • 如何访问原始对象以及plays注释?
    根据我传递给values的内容,这只给了我一定的价值。我更愿意访问原始对象 - 该模型有我想要调用的方法。

  • 如何从SongPlay分组到Artist 我想展示艺术家的图表,以及歌曲图表。

2 个答案:

答案 0 :(得分:3)

您可以在valuesannotate中使用相同的字段。

您拥有Song对象的主键(您可以使用song代替song__id),因此请使用

Song.objects.get(id=...)

对于您的第二个问题,请使用song__artist作为valuesannotate中的字段执行单独查询:

from django.db.models import Count

SongPlay.past_month
    .filter(user=user)
    .values('song__artist')
    .annotate(plays=Count('song__artist'))
    .order_by('-plays')[:20]

答案 1 :(得分:0)

agf已经向您展示了如何按song_artist进行分组。我要做的是获取实际的Song对象是将它存储在memcached中,或者如果您调用的方法相当简单,则将其作为静态方法或类方法。您也可以使用查询中的数据初始化Song对象,而不是实际保存它以访问此方法。可能有助于了解您想要从Song对象调用的方法的详细信息。