Search code examples
pythondjangodjango-modelsmany-to-manymultiset

Django ManyToManyField as multiset


Is there any way how to store the same object in m2m field multiple times?

Let's say I have the following models

class Item(models.Model):
    name = models.CharField(max_length=64)


class Inventory(models.Model):
    items = models.ManyToManyField('Items', blank=True)

And I create some instances

>>> inventory = Inventory()
>>> inventory.save()

>>> item1 = Item(name='Item 1')
>>> item1.save()

>>> item2 = Item(name='Item 2')
>>> item2.save()

Now I want to add those instances of item to the inventory multiple times.

>>> inventory.items.add(item1)
>>> inventory.items.add(item2)

>>> inventory.items.all()
[<Item: Item 1>, <Item: Item 2>]

>>> inventory.items.add(item1)

>>> inventory.items.all()
[<Item: Item 1>, <Item: Item 2>]

So ManyToManyField works like a set, is there any way to achieve the behavior of a multiset?


Solution

  • Instead of storing Item's in your inventory, you can store InventoryItem's

    class InventoryItem(models.Model):
        item = models.ForeignKey(Items)
        quantity = models.SmallIntegerField(default=1)
        inventory = models.ForeignKey(Inventory)
    

    The idea is you introduce a middle class that handles the quantity for you, as well as potentially other things like should the item be stackable.

    The only alternative I can think of is to duplicate an item object and then store both of these in the inventory - which may or may not be better for your use case