views:

64

answers:

2

Hey,

I want to model the following situation. I have a table of items, and a table of players, and a player can have many items and have multiple copies of the same item. I can easily model the player having multiple items:

class Item(models.Model):
    name = models.CharField(max_length = 200, blank = False)

class Player(models.Model):
    items = models.ManyToManyField(Term)

But I want to know the number of each item the player has i.e. each items frequency. How can I best model this in Django. (I've simplfied my actual models/problem to get my point accross :) )

Cheers,

Pete

+5  A: 

Use an explicit through table with a quantity field.

Daniel Roseman
+1  A: 

If the items are non-unique you can use a PlayerItem model and define it as a through model as Daniel Roseman suggested. To avoid saving the same item twice you can use unique_together:

class Item(models.Model):
    name = models.CharField(max_length = 200, blank = False)

class Player(models.Model):
    items = models.ManyToManyField(Item, through='PlayerItem')

class PlayerItem(models.Model):
    player = models.ForeignKey(Player)
    item = models.ForeignKey(Item)
    quantity = models.IntegerField(default=1)

    class Meta:
        unique_together = ('player', 'item')

However if the items will vary slightly or you need to store acquisition date for instance, you need a different setup:

class Item(models.Model):
    name = models.CharField(max_length = 200, blank = False)

class Player(models.Model):
    items = models.ManyToManyField(Item, through='PlayerItem')

class PlayerItem(models.Model):
    player = models.ForeignKey(Player)
    item = models.ForeignKey(Item)
    acquired = models.DateTimeField(default=datetime.datetime.now)

This time you will be saving duplicates of (player, item) tuple, one for each item. And then you can get the number of a specific item via count().

I would also like to note that you can't reach PlayerItem model from neither Item nor Player. In both cases you need to query PlayerItem directly to access the extra fields. (as documented)

muhuk