I would create 3 tables, one of which contained two foreign keys to each of the other two tables. For this reason, I find the Django manytomany field very unnatural.
This is exactly what Django is doing behind the curtains. If you inspect the database, you will see a junction table [wiki]. Django simply does this in the background. It simply presents it to the foreground as a field. As you can see in the database Representation of the ManyToManyField
[Django-doc]:
Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the name of the table for the model that contains it. Since some databases don't support table names above a certain length, these table names will be automatically truncated and a uniqueness hash will be used, e.g. author_books_9cdf
. You can manually provide the name of the join table using the db_table
option.
You can even add extra fields to this junction table, by defining the model in between explicitly, and specify this in the through=…
parameter [Django-doc]. For example:
class Category(models.Model):
name = models.CharField(
max_length=128,
unique=True
)
class Item(models.Model):
name = models.CharField(
max_length=128,
unique=True
)
categories = models.ManyToManyField(
Category,
through='ItemCategory'
related_name='items'
)
class ItemCategory(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
validated = models.BooleanField(default=False)
A ManyToManyField
is thus more a concept to make representing and querying more convenient.