【问题标题】:Pulling a username - 'ManyRelatedManager' object does not support indexing提取用户名 - 'ManyRelatedManager' 对象不支持索引
【发布时间】:2013-10-15 23:41:39
【问题描述】:

我正在创建一个允许用户玩异步游戏的网站。我正在使用 Python 2.7.5 运行 Django 1.5,并使用 Django 的本机用户身份验证 API。我没有创建自定义 User 模型,而是将每个用户链接到自定义 UserDetails 类。 UserDetails类的相关代码在这里:

    class UserDetails(models.Model):
        user = models.OneToOneField(User)
        join_date = models.DateTimeField(auto_now_add=True)
        games = models.ManyToManyField(Game, default=None)

每个游戏都使用 ManyToMany 字段链接到 UserDetails。来自game.models的相关代码在这里:

    class Game(models.Model):
        title = models.CharField(max_length=60)
        create_date = models.DateTimeField(auto_now_add=True)
        started = models.BooleanField(default=False)
        players = models.ManyToManyField('user.UserDetails', default=None)

在首页,我想要一个表格,列出所有正在进行的游戏。在views.py中,我使用了这个命令:

    games_in_signup = Game.objects.filter(started=False)

...并将其传递给模板。最后,在模板中我有这个代码来生成表格的行:

    {% for g in games_in_signup %}
    <tr>
        <td>{{ g.title }}</td>
        <td>{{ g.players|first }}</td>
        <td>{{ g.number_of_players }}</td>
        <td>{{ g.players.all|length }}</td>
        <td>{{ g.create_date }}</td>
    </tr>
    {% endfor %}

我没有像我希望的那样给我第一个玩家的用户名,而是得到 “TypeError at /game/ 'ManyRelatedManager' 对象不支持索引”。如果我尝试改变

        <td>{{ g.players|first }}</td>    

...到...

        <td>{{ g.players.all|first }}</td>

...我得到 "AttributeError at /game/ 'UserDetails' 对象没有属性 'username'".

按照我的设置方式,游戏运行良好,但这让我很不舒服。可能有比这更好的设置方法,我欢迎在这方面提供任何建议。无论如何,您知道我如何获取模板以将用户名第一个玩家从每个游戏的玩家列表中拉出吗?谢谢!

【问题讨论】:

  • 您在某处引用.username 吗?可能在__unicode__ ??
  • 就是这样 - 请参阅丹尼尔的回答。谢谢!

标签: python django django-models django-users django-orm


【解决方案1】:

这里有几个问题。

首先,你不需要在 Game 和 UserDetails 之间的关系两侧使用 ManyToManyFields。 Django 会自动为您提供反向关系,就像使用 ForeignKeys 一样。您应该选择一侧并仅在那里定义字段。

其次,你没有显示username 的使用位置,但我猜你已经在 UserDetails 上定义了一个__unicode__ 方法,类似于return self.username。但是,username 不是 UserDetails 上的字段,而是链接的 User 表上的字段 - 所以它应该是 self.user.username

最后,我完全不知道你为什么使用players,而不是players.all:你看到它给你一个错误,而且你在length以后的调用中正确使用了players.all .但是请注意,这是非常低效的:您应该在那里使用players.count

【讨论】:

  • 这做得很完美。你是对的——我确实在 UserDetails 上定义了一个 unicode 方法,并像你建议的那样对其进行了修改。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2014-04-23
  • 2019-11-12
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 2018-01-07
  • 2013-06-23
相关资源
最近更新 更多