我有一个Genre
和一个User
模特。每个Genre
都有一个id
和一个name
,并且存在多对多关系,因此每个都User
喜欢0或更大Genres
。
是否有一个有效的查询来获取后代在所有用户中每个流派有多少喜欢?
我目前的方法可行,但效率极低,因为它必须读取每种类型的所有用户的所有赞:
In [1]: genres = list(Genre.objects.values('name', 'id'))
In[2]: genres
Out[2]:
[{'id': 10, 'name': 'Rock'},
{'id': 11, 'name': 'Pop'},
{'id': 12, 'name': 'Hip hop'},
{'id': 13, 'name': 'Electronic'},
{'id': 14, 'name': 'Classical'}]
In [3]: likes_by_users = []
In [4]: users = list(User.objects.all())
In [5]: for u in users:
...: current_user_likes = []
...: likes_by_users.append(current_user_likes)
...: for lg in u.liked_genres.all():
...: current_user_likes.append(lg.pk)
In [6]: likes_by_users
Out[6]:
[[14],
[11, 12],
[11, 10, 13, 12],
[],
[13, 12, 10, 1
[10, 11]]
In [7]: counts = {}
In [8]: for g in genres:
...: counts[g['id']] = {
...: 'name' : g['name'],
...: 'likes': 0
...: }
...: for l in likes_by_users:
...: for gid in l:
...: if gid == g['id']:
...: counts[gid]['likes'] += 1
In [9]: ranking = sorted(list(counts.values()), key=lambda x : x['likes'], reverse=True)
这正是我需要的输出:
In [9]: ranking
Out[9]:
[{'likes': 4, 'name': 'Pop'},
{'likes': 3, 'name': 'Rock'},
{'likes': 3, 'name': 'Hip hop'},
{'likes': 2, 'name': 'Electronic'},
{'likes': 1, 'name': 'Classical'}]
是否有查询或其他方法可以有效地获得所需的排名?
Django中的ManyToMany字段由实际模型(以及表)支持。
您可以通过.through
以下方式获取支持模型:
GenreLikes = User.liked_genres.through
对于简单许多一对多的关系,该模型有两个字段/列,user
并genre
在你的情况下,一个实例/每用户喜欢对行。
因此,您应该可以通过
GenreLikes.objects.values('genre').annotate(likes=Count('user')).order_by('-likes')
或类似。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句