3

我有一些记录人们聆听习惯的 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。我更愿意访问原始对象——模型有我想调用的方法。

  • 我如何分组 from SongPlayto Artist 我想展示一张艺术家图表,以及一张歌曲图表。

4

2 回答 2

4

values您可以在和中使用相同的字段annotate

你有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]
于 2012-04-16T21:04:12.527 回答
0

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

于 2012-04-16T22:02:54.610 回答