拉取用户名 - "ManyRelatedManager"对象不支持索引

Rob*_*ins 2 python django django-models django-orm django-users

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

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

每个游戏都使用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)
Run Code Online (Sandbox Code Playgroud)

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

    games_in_signup = Game.objects.filter(started=False)
Run Code Online (Sandbox Code Playgroud)

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

    {% 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 %}
Run Code Online (Sandbox Code Playgroud)

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

        <td>{{ g.players|first }}</td>    
Run Code Online (Sandbox Code Playgroud)

...至...

        <td>{{ g.players.all|first }}</td>
Run Code Online (Sandbox Code Playgroud)

...我在/ game /'UserDetails'对象中获得"AttributeError"没有属性'username'".

游戏运行得很顺利我设置的方式,但这给了我适合.设置它可能有比这更好的方法,我欢迎任何有关这方面的建议.在任何情况下,你知道如何让模板从每个游戏的玩家列表中拉出用户名第一个玩家吗?谢谢!

Dan*_*man 5

你有几个问题在这里.

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

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

最后,我不确定你为什么要使用它players,而不是players.all:你看到它会给你一个错误,而且你之后players.alllength呼叫中正确使用了.但请注意,这是非常低效的:你应该在players.count那里使用.