django difference between - one to one, many to one and many to many

Especially with django, which makes complicated db design a piece of cake, I think it's very important to understand how they work on the SQL level to better understand anything you are doing. I think an example is the best way to understand this.

First thing you should understand is that each SQL table has one field (which is usually automatically incremented) which is called a 'primary-key'. This field is a column with a unique value for each row.

Say in django you create a model representing an author, which has three fields - first_name, last_name and an optional field containing email. Django will also automatically add the primary-key field and call it pk (you can also decide to define your own field to use as primary key but usually don't). So when using the command manage.py syncdb it will create a table that looks like this:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+

When you add a new value (say 'Stephen King') it would add it to the authors table like so:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+
|  1 | Stephen    | King      | [email protected] |
+----+------------+-----------+-----------------------+

Let's add another one:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+
|  1 | Stephen    | King      | [email protected] |
|  2 | J.D.       | Salinger  |                       |
+----+------------+-----------+-----------------------+

That's simple. Now we add a new model called Book:

+----+--------------+--------+--------+
| pk |    title     | genre  | author |
+----+--------------+--------+--------+
|  1 | Pet Semetary | Horror |      1 |
+----+--------------+--------+--------+

Now see what I did there? at the field for author I gave book the value for Stephen King's primary key - remember, it is unique, so it will only fetch back Stephen King. That's a ForeignKey - it points to a pk on a related table, and represents a Many-To-One relationship, i.e. various books can point to the same pk of one author, but not the other way around. That way each author can have many related books, but every book has only one author.

Now let's say we want to add another book by Stephen King. This one is called The Talisman:

+----+--------------+---------+--------+
| pk |    title     |  genre  | author |
+----+--------------+---------+--------+
|  1 | Pet Semetary | Horror  |      1 |
|  2 | The Talisman | Fantasy |      1 |
+----+--------------+---------+--------+

But uh oh, wait - this last one was actually co-written with another author called Peter Straub. So what do we do? We need first to add Straub to our authors table:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+
|  1 | Stephen    | King      | [email protected] |
|  2 | J.D.       | Salinger  |                       |
|  3 | Peter      | Straub    |                       |
+----+------------+-----------+-----------------------+

But now how do we tell the tables that The Talisman is related to two different rows? Simple - use a third table to link the two.

So table one would be authors (as seen above). second table will be books. and the third table will be called authors_books and will look like this:

+------------+--------------+
| pk_of_book | pk_of_author |
+------------+--------------+
|          1 |            1 |
|          2 |            1 |
|          2 |            3 |
+------------+--------------+

See? It tells you how to link different pks between the tables. This is a Many-To-Many relationship, because different books can be related to different authors and vice versa. And the three-table schema I described is the basic design for it.

OneToOne relationships are like ForeignKey but with a unique=True so you can only link between one object to another object and that's it. It is usually used when you want to expand a certain model without changing the original (say you want to add your own custom field to the built in User model).

Hope that helps clear things up. Django is so wonderful that you almost never need to use SQL, but it still helps to know a little about what's happening in the background. There are plenty explanations about those relationship out in the web, I only gave you a small general intro about it, and I strongly suggest you google around a bit and expand your understanding for yourself. good luck!


The relations are a general concept on relational databases like MySQL. Everything regarding to relations and Django´s ORM is very well explained here: https://docs.djangoproject.com/en/dev/topics/db/models/#relationships.

Hope this leads into the right direction.