I've read a few places (see the second answer) that one-to-one relationships in Django models should almost always only be used for inheritance, or to access an otherwise inaccessible model (like the Django user model).
However, it seems like there are cases where you have an object that will always have exactly one instance of another object where you would logically want to separate those two objects. Say, for example, your app was storing information about cars. Each car has exactly one driver and each driver only drives one car. Does it not make sense to separate car and driver into two separate models?
Imagine you have a company and make intranet tool listing all employees, their positions, offices, departments, salaries, etc. You would make in Django models.py a class Employee, maybe something like this:
class Employee(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
position = models.CharField(max_length=255)
office = models.CharField(max_length=20)
salary = models.IntegerField()
department = models.ForeignKey(Department, related_name='employees')
But for some reasons you don't want the salary to be accessible to all employees, maybe there are many people with redactor status in the admin area, and decide to outsource it to its own model and change the model Employee:
class Employee(models.Model):
# above attributes
salary = models.OneToOneField(Salary)
There are certainly other ways to hide this information, but one possibility is to divide the information in two tables even though it is just plain 1:1 relation.
Your company is a software company and you introduce pair programming. Every employee has a pair programming partner. It can be just one programming partner. So you adapt your model again:
class Employee(models.Model):
# above attributes
pair_programmer = models.OneToOneField('self')
This would be a recursive one-to-one relation.
One-to-one relations are not very common and hard to find in beginners' tutorials, but if there are some specific requirements, you find yourself creating 1:1 relation for solving the problem.
Here is a real life example from my work. I'm bioinformatician and make software for microorganisms. They are classed in genera and species. Every genus may contain one or more species, but a species can belong to only one genus. That is a clear 1:n relation. But now, a genus has a type species, only one and just one. And the type species can belong to one genus. Here I put models.OneToOneField
, besides the models.ForeignKey
.
Don't worry a lot about 1:1 relations in advance. When you come to some specific problem, then you'll figure out if you need 1:1 relation.