views:

401

answers:

3

I have two models in my Django project:

  • Match
  • Player

Match has a ManyToMany property pointing at players, so that multiple players can compete in a match. I'd like to return an informative object name in the Django admin, something like "Richard Henry vs John Doe", by using a join on the players' full names. However the following fails:

class Match(models.Model):
 players = models.ManyToManyField(Player, verbose_name='Competitors')

 def __unicode__(self):
  return " vs ".join(self.players)

Are ManyToManyFields not just lists? Why can't I join them? Any input is appreciated. Here's my player model, incase that helps:

class Player(models.Model):
 full_name = models.CharField(max_length=30)

 def __unicode__(self):
  return "%s" % self.full_name

Thanks!

Edit: I just discovered that I can use self.players.list_display to have this returned as a list. I'm no longer spat a traceback, but for some reason the __unicode__ name now returns None. Any idea why that would be?

Edit 2: Changed code:

class Match(models.Model):
 players = models.ManyToManyField(Player, verbose_name='Competitors')

 def __unicode__(self):
  return " vs ".join(self.players.list_display)
+4  A: 

"Are ManyToManyFields not just lists?"

No.

They're querysets. Which are list-like, but not actually lists.

Do this.

return " vs ".join(list(self.players))

The list function will force evaluation of the query set and return a list object.

S.Lott
A: 

No, ManyToManyField is not a list, it's just a single key and there will be one Match instance for each player in the match.

You don't want to do a query in the __unicode__() method because it will most likely be a big performance hit. Just display the X vs. Y in your template.

Van Gale
A: 

Another option is:

return " vs ".join([p.full_name for p in self.players.all()])

Note: Sorry for bringing this back -- gravedigger :-)

jweyrich