I'm creating on a website that allows users to play an asynchronous game. I'm running Django 1.5 with Python 2.7.5, and using Django's native user authentication API. Rather than create a custom User model, I've linked each user to a custom UserDetails class. The relevant code for the UserDetails class is here:

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

Each game links to the UserDetails with a ManyToMany field. Relevant code from the game.models here:

    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)

On the front page, I want to have a table listing all the games in progress. In the views.py, I'm using this command:

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

...and passing it to the template. Finally, in the template I have this code to generate the rows of the table:

    {% 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 %}

Instead of giving me the username of the first player, as I would wish for, I get "TypeError at /game/ 'ManyRelatedManager' object does not support indexing". if I try changing

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

...to...

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

...I get "AttributeError at /game/ 'UserDetails' object has no attribute 'username'".

The games run fine with how I have it set up, but this has been giving me fits. There may be a better way to set it up than this, and I'd welcome any advice in that respect. In any case, do you know how I can get the template to pull the username first player out of the list of players for each game? Thanks!

有帮助吗?

解决方案

You have a couple of issues here.

Firstly, you don't need ManyToManyFields on both sides of the relationship between Game and UserDetails. Django automatically gives you a reverse relationship, just like with ForeignKeys. You should choose one side and define the field there only.

Secondly, you don't show where username is being used, but I guess you have defined a __unicode__ method on UserDetails which is something like return self.username. However, username is not a field on UserDetails, but on the linked User table - so it should be self.user.username.

Finally, I'm not sure why you have used players at all, instead of players.all: you see it gives you an error, and furthermore you have correctly used players.all in the length call later. However, note that this is extremely inefficient: you should be using players.count there.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top