Dan Mantyla
Dan Mantyla

Reputation: 1870

Django manytomany: adding multiple, non-unique relationships?

I'm building an app that puts together the hardware of a computer. This is my first time working with django. Say I have the following models:

class Memory(models.Model):
    partNum = models.CharField()
    capacity = models.CharField()

class Computer(models.Model):
    name = models.CharField()
    memory = models.ManyToManyField(Memory)
    # also has cpus, hard drives, and motherboard, but focus on memory for now

One memory object can belong to many computer objects, and one computer object can have many memory objects - hense Many-To-Many. However, computers require the same exact memory sticks installed if using more than one.

Yet django's manytomany field (by default?) only allows one instance of a memory-computer relationship, it must me unique. Any way around this?

If I try, in the admin page, to add many of the same memory objects to a computer, it says "Computer-memory relationship with this Computer and Memory already exists". If I try adding more than once the same memory object to a server object in the manage.py shell, it appears that only one memory object was added. If I try to manually edit the database to have a duplicate entry, I get an error saying that the entry already exists. I see that in the database structure, some sorta "unique together" index thingy is enforcing is enforcing this. If I altered the table to remove that clause, would that solve my problem? Probably not unless the django manager is more stupid than expected.

What are my options? Write my own intermediary models and use the through construct? But then I won't get to use the cool filter_horizontal widget! Rewrite my Computer model to have a Foreign Key field plus a field for the number of memory object? But then I won't get the ManyToMany API facilities. Help!

Upvotes: 3

Views: 4671

Answers (2)

Saransh Mohapatra
Saransh Mohapatra

Reputation: 9636

No this is not a compromise, Even if you dont create another table for the through thing, than also django will create it to remember exactly which memory is associated with each computer, so better is that you do it yourself...and this also allows you to get other fields in there that are required for a specific computer with a specific memory

Upvotes: 0

nilu
nilu

Reputation: 940

Edit: sorry, I did not read your post well enough, about not wanting to use 'through'.

One way to circumvent the problem, would be to use the "through" parameter, in which you can manually specify an intermediate model to use for the many-to-many relationship. In this way, you should still have (most of) the many-to-many facilities that Django provides.

The intermediate model could then have count (which I would find easier to manage than having multiple relations):

class Memory(models.Model):
    partNum = models.CharField()
    capacity = models.CharField()

class Computer(models.Model):
    name = models.CharField()
    memory = models.ManyToManyField(Memory, through='ComputerMemory')

class ComputerMemory(models.Model):
    memory = models.ForeignKey(Memory)
    computer = models.ForeignKey(Computer)
    count = models.IntegerField()

For further information, take a look in the Django documentation: https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

Upvotes: 7

Related Questions