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

Sam*_*ing 3 python sql django

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

\n\n
class Artist(models.Model):\n    name = models.CharField()\n\nclass Song(models.Model):\n    artist = models.ForeignKey(Artist)\n    title = models.CharField()\n\nclass SongPlay(models.Model):\n    song = models.ForeignKey(Song)\n    user = models.ForeignKey(User)\n    time = models.DateTimeField()\n\nclass User(models.Model):\n    # doesn't really matter!\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

到目前为止我想出的最好的办法是:

\n\n
SongPlay.past_month\n    .filter(user=user)\n    .values('song__title', 'song__id', 'song__artist__name')\n    .annotate(plays=Count('song'))\n    .order_by('-plays')[:20]\n
Run Code Online (Sandbox Code Playgroud)\n\n

上面past_month是一个仅过滤上个月的比赛的经理。假设我们已经获得了user要过滤的正确对象。

\n\n

我想我的两个问题是:

\n\n
    \n
  • 如何访问原始对象以及注释plays
    \n这只是根据我传递给 的内容给了我某些值values。我更愿意访问原始对象 \xe2\x80\x93 该模型具有我想调用的方法。

  • \n
  • 我怎样才能从SongPlay到分组Artist\n我想显示艺术家图表以及歌曲图表。

  • \n
\n

agf*_*agf 6

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

您拥有对象的主键Song(您可以使用song而不是song__id),因此使用

Song.objects.get(id=...)
Run Code Online (Sandbox Code Playgroud)

对于第二个问题,请使用andsong__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]
Run Code Online (Sandbox Code Playgroud)