OneToOne
A OneToOne field is a ForeignKey with a UNIQUE constraint — each row on one side relates to exactly one row on the other.
Defining a OneToOne
class User(Model):
username = CharField(max_length=100, unique=True)
email = CharField(max_length=254, unique=True)
class Profile(Model):
user = OneToOneField(User, on_delete="CASCADE")
bio = CharField(max_length=500, null=True, blank=True)
avatar = CharField(max_length=500, null=True, blank=True)
This creates a user_id column with both a foreign key and a unique constraint.
When to Use OneToOne
- Extending a built-in model — Add fields to a model you can't modify
- Splitting large tables — Keep frequently-accessed fields separate from rarely-used ones
- Inheritance-like patterns — Model subtypes without actual inheritance
# Base user data (frequently queried)
class User(Model):
username = CharField(max_length=100)
password = CharField(max_length=255)
# Extended profile (rarely queried)
class Profile(Model):
user = OneToOneField(User, on_delete="CASCADE")
bio = CharField(max_length=500, null=True)
website = CharField(max_length=200, null=True)
location = CharField(max_length=100, null=True)
Accessing Related Objects
# User → Profile
user = await User.objects.get(pk=1)
profile = await Profile.objects.get(user_id=user.pk)
# Profile → User
profile = await Profile.objects.get(pk=1)
print(profile.user.username) # Forward descriptor (lazy-loaded)
Next Steps
→ ManyToMany — Many-to-many relationships