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)