Django在非外键字段上进行连接

1 投票
1 回答
41 浏览
提问于 2025-04-14 15:51

我刚接触Django,正在制作一个游戏,游戏中有一个环节是玩家互相投票。

这是我设置的模型(只列出相关字段)

#models.py
class Game(models.Model):
  gamecode = ShortUUIDField(length=4, max_length=4, unique=True)
  phasenumber = models.IntegerField(default=1)
  isActive = models.BooleanField(default=True)

class Player(models.Model):
  game = models.ForeignKey(Game, on_delete=models.CASCADE)
  user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
  isPlaying = models.BooleanField(default=True)

class PlayerVote(models.Model):
  byplayer = models.ForeignKey(Player, on_delete=models.CASCADE)
  forplayer = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="voteforplayer")
  gamephasenumber = models.IntegerField()
  timestamp = models.DateTimeField(auto_now_add=True)

当一个用户加入游戏时,他们在“玩家”模型中会有一个记录;当他们给其他玩家投票时,“玩家投票”模型中会增加一条记录,显示是谁投的票(byplayer)以及他们投给了谁(forplayer)。

我想做的是创建一个查询集,里面包含每个玩家和他们获得的票数。

我尝试过使用annotate,这个方法似乎可以给我票数的统计,但它默认是根据投票者的字段来连接,所以我得到的是每个玩家投出的票数,而不是他们收到的票数。

在SQL中,我只需要做一个连接:Player.pk = PlayerVote.forplayer.pk,在Django中能做类似的操作吗?

另外,我也可以创建一个额外的模型来总结每个玩家收到的票数,每投一票就加1,但这样似乎有点多余。

1 个回答

0

你可以使用 .annotate(…) [Django-doc] 来进行一些操作:

from django.db.models import Count

Player.objects.annotate(score=Count('voteforplayer'))

通过这个 QuerySet 得到的 Player 对象会多一个属性 .score,这个属性里会存储与该玩家相关的投票数量,但它是根据 forplayer_id 来计算的。

撰写回答