1

我有以下型号:

class UserProfile(models.Model):
    user = models.OneToOneField(User) 
    score = models.PositiveIntegerField()

class Game(models.Model):
    name = CharField(max_length=100)

class Achievement(models.Model):
    user = models.ForeignKey('User')
    game = models.ForeignKey(Game)

在 settings.py 中,我设置AUTH_PROFILE_MODULE了我的 UserProfile 类。

对于给定的游戏,我想获得一个用户列表,例如,该游戏的成就超过五个。

所以我做了以下事情:

candidates = Achievement.objects.filter(game=game).values('user').annotate(nba=Count('id')).filter(nba__gte=5).order_by('-user__userprofile__score')

现在它可以工作了,但问题是我得到了一个包含用户 ID 和他的 nba(成就数量)的值列表。但我需要在模板中打印分数并访问 UserProfile 的其他属性...

所以我尝试将“.values('user')”更改为:

.values('user','user__userprofile__score')

但它不起作用!我收到一个错误:

invalid field user__userprofile__score

请注意,如果我这样做,它会起作用:

.values('user','user__username')

这似乎表明可以在属性上调用值但不能在外键上调用值?

我还尝试了另一种使用“django-batch-select”应用程序的方法:

batch = Batch('achievement_set').filter(game=game)
candidates = User.objects.batch_select(achieved=batch).exclude(achieved__is_null=True)

但我收到一个错误:

Cannot resolve keyword 'achieved' into field.

如果我删除“排除”语句,它会起作用,但是我会得到一个所有用户的列表,包括那些在这个游戏中没有任何成就的用户(他们得到:实现 == [])

我一直在到处寻找,但找不到解决我的问题的方法……我们将不胜感激!

4

2 回答 2

0

您可以通过一个额外的查询来获取用户配置文件:

UserProfile.objects.filter(user_id__in=[x['user'] for x in candidates])
于 2011-06-10T10:29:03.343 回答
0

我认为您必须删除values('user')并添加到 query_set 的末尾only('user', 'user__profile')select_related('user', 'user__profile')

candidates = [i.user for i in Achievement.objects.\
    select_related('user', 'user__userprofile').\
    annotate(nba=Count('id')).\
    filter(game=game, nba__gte=5).\
    only('user', 'user__userprofile').\
    order_by('-user__userprofile__score')]

我在我的项目上进行了测试select_related并且only它有效

>>> db.connection.queries = []
>>> p = [(i.object, i.object.owner) for i in models.ImageOrVideo.objects.\
      select_related('object', 'object__owner').\
      only('object').all().\
      order_by('-object__owner__id')]
...
>>> len(db.connection.queries)
1
于 2011-06-10T15:06:16.573 回答