【问题标题】:Django: Sort a queryset by counting the many to many objectsDjango:通过计算多对多对象对查询集进行排序
【发布时间】:2016-10-16 21:15:39
【问题描述】:

我到处搜索,但找不到这个问题的解决方案,乍一看应该是微不足道的。

请考虑 Djano 模型:

class UserModel(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    institution=models.CharField(max_length=128)


class TeamModel(models.Model):
    creator= models.ForeignKey(UserModel,related_name='creator')
    members= models.ManyToManyField(UserModel,related_name='teams'))
    name=models.CharField(max_length=64)`

那些模型是固定的,我不能改变它们。我当然可以包含新字段。

要检索与用户关联的团队,我可以这样做:

queryset= instance_UserModel.teams.all()

完美运行!现在我想按成员数量对团队进行排序。

queryset= queryset.annotate(num_members=Count('members')).order_by('num_members')

它不起作用,因为 num_members 值始终为“1”!

print queryset[0].num_members
print queryset[1].num_members

总是返回“1”。怎么回事???!!!

提前谢谢你,

CBar

【问题讨论】:

  • 澄清一下,querysetannotate 对应的行相当于instance_UserModel.teams.all()TeamModel.objects.all()?
  • 请按原样复制粘贴您的代码,您的代码中至少有 2 个拼写错误会引发语法错误。
  • 亲爱的 Lorenzo,按照我在 Django 文档中的理解,queryset 是相当于 TeamModel.objects.all() 的对象集合。
  • queryset 等价于 instance_UserModel.teammodel_set.all()。还有 instance_UserModel=UserModel.objects.get(user=request.user)。
  • 抱歉错别字 C14。我稍微修改了原始代码中的变量名称以使其更清晰。下次我会照你说的做。

标签: django count many-to-many django-queryset


【解决方案1】:

这没有经过测试

class TeamModel(models.Model):
    creator= models.ForeignKey(UserModel,related_name='creator')
    members= models.ManyToManyField(UserModel,related_name='teams'))
    name=models.CharField(max_length=64)`

views.py

import operator

teams = TeamModel.objects.all()
team_member_count = {}
for team in teams:
   team_member_count[team.name] = team.members.all.count()

sorted_teams_by_member_count = sorted(team_member_count.items(), key=operator.itemgetter(1))

【讨论】:

  • 亲爱的 rwx,我不明白这将如何为特定用户选择团队。如果我错了,请纠正我,但我知道你的代码只创建了一个带有团队和计数的元组的排序列表。为此,我宁愿写 TeamModel.objects.all().annotate(num_members=Count('members')).order_by('num_members')。还是谢谢你。
【解决方案2】:

我找到了一个解决方案,但我不知道它在数据库操作方面的效率如何。而且我仍然不明白为什么我以前的代码不起作用。

    qUserTeams=instance_UserModel.teams.all()
    qAllTeams=TeamModel.objects.all().annotate(num_members=Count('members')).order_by('num_members')
    queryset= qAllTeams & qUserTeams

【讨论】:

    猜你喜欢
    • 2014-07-23
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-03-22
    • 2011-11-29
    • 2022-01-24
    • 2015-01-26
    • 1970-01-01
    相关资源
    最近更新 更多