【问题标题】:In Django, how do you retrieve data from extra fields on many-to-many relationships without an explicit query for it?在 Django 中,如何在没有显式查询的情况下从多对多关系的额外字段中检索数据?
【发布时间】:2010-10-04 08:17:38
【问题描述】:

假设在 Django 1.0 中你有 extra data on a Many-to-Many relationship:

class Player(models.Model):
  name = models.CharField(max_length=80)

class Team(models.Model):
  name = models.CharField(max_length=40)
  players = models.ManyToManyField(Player, through='TeamPlayer', related_name='teams')

class TeamPlayer(models.Model):
  player = models.ForeignKey(Player)
  team = models.ForeignKey(Team)
  captain = models.BooleanField()

多对多关系允许您使用属性(Team 对象上的“players”属性或通过其相关名称使用 Player 对象上的“teams”属性)访问相关数据。当其中一个对象被放置到模板的上下文中时(例如,团队放置在上下文中以渲染生成团队名单的模板),可以访问相关对象(即团队中的球员),但是如何访问额外数据(例如“队长”)与上下文中对象(例如团队)中的相关对象一起被访问,而不向上下文中添加额外数据?

我知道可以直接查询中间表以获取额外数据。例如:

TeamPlayer.objects.get(player=790, team=168).captain

或者:

for x in TeamPlayer.objects.filter(team=168):
  if x.captain:
    print "%s (Captain)" % (x.player.name)
  else:
    print x.player.name

直接在中间表上执行此操作需要我将其他数据放置在模板的上下文中(TeamPlayer 上的查询结果),如果可能发生这种情况,我会尽量避免这样做。

【问题讨论】:

    标签: python django manytomanyfield


    【解决方案1】:

    所以,在提出问题 15 分钟后,我找到了自己的答案。

    使用dir(Team),我可以看到另一个名为teamplayer_set 的生成属性(它也存在于播放器上)。

    t = Team.objects.get(pk=168)
    for x in t.teamplayer_set.all():
      if x.captain:
        print "%s (Captain)" % (x.player.name)
      else:
        print x.player.name
    

    不确定如何自定义生成的related_name,但至少我知道我可以从模板中获取数据,而无需在上下文中添加额外的查询结果。

    【讨论】:

    • 如果这样做,每次执行 x.play.name 时都会查询 DB(以便从 DB 中获取 Player)。查找 selected_related 的文档。
    • 是的。我仍在学习 django(和 python),但我知道 select_related()。为了示例的简单性,我将其省略了。
    • 我处于完全相同的情况(django noob 与 ManyToMany 情况),我想知道是否有一种在模板下显示这些数据的好方法。例如,如果我想显示每支退出的球队,而在每支球队的下方只显示队长。我是否必须先遍历每个团队,然后遍历每个 teamplayer_set 条目?
    • 我怀疑答案是“是”,因为您在上下文中只有 teamplayer_set 可供您使用(因此您必须对其进行迭代以获得所需的数据)。但在你所说的情况下,将更多数据添加到上下文中可能更有意义——比如 TeamPlayer.objects.filter(captain=true)
    猜你喜欢
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    相关资源
    最近更新 更多