~2 min read • Updated Mar 10, 2026
1. Defining a One‑to‑One Relationship
A one‑to‑one relationship is defined using OneToOneField.
In the example below, each Place may optionally have one Restaurant, and each Restaurant corresponds to exactly one Place.
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(models.Model):
place = models.OneToOneField(
Place,
on_delete=models.CASCADE,
primary_key=True,
)
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)
2. Creating Data
Creating Place instances:
p1 = Place(name="Demon Dogs", address="944 W. Fullerton"); p1.save()
p2 = Place(name="Ace Hardware", address="1013 N. Ashland"); p2.save()
Creating a Restaurant:
The Restaurant uses the Place as its primary key:
r = Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False)
r.save()
3. Accessing the Relationship
Restaurant → Place:
r.place
Place → Restaurant:
p1.restaurant
If a Place has no Restaurant:
hasattr(p2, "restaurant") # False
4. Reassigning a One‑to‑One Relationship
You can assign a Restaurant to a different Place:
r.place = p2
r.save()
p2.restaurant # Now belongs to p2
And assign it back from the reverse side:
p1.restaurant = r
p1.restaurant
Important: The related object must be saved first
p3 = Place(name="Demon Dogs", address="944 W. Fullerton")
Restaurant.objects.create(place=p3, ...) # ValueError
5. Querying Across One‑to‑One Relationships
Restaurant → Place:
Restaurant.objects.get(place=p1)
Restaurant.objects.filter(place__name__startswith="Demon")
Restaurant.objects.exclude(place__address__contains="Ashland")
Place → Restaurant:
Place.objects.get(restaurant=r)
Place.objects.get(restaurant__place__name__startswith="Demon")
6. Deletion Behavior (CASCADE)
Deleting a Place deletes its Restaurant automatically:
p2.delete()
Restaurant.objects.all() # Only the restaurant for p1 remains
7. Related Models: Waiter
In the example, Waiter has a ForeignKey to Restaurant:
w = r.waiter_set.create(name="Joe")
Querying Waiters:
Waiter.objects.filter(restaurant__place=p1)
Waiter.objects.filter(restaurant__place__name__startswith="Demon")
Conclusion
One‑to‑one relationships in Django are ideal when two models should form a strict pair.
Using OneToOneField, you can easily define the relationship, navigate it from both sides, reassign linked objects, and perform expressive queries.
Django’s reverse managers and lookup chaining make working with one‑to‑one relationships intuitive and powerful.
Written & researched by Dr. Shahin Siami