Lesson 39 of 60 – Django OneToOneField
65%

Django OneToOneField

The OneToOneField is used to create a one-to-one relationship between two Django models.

In a one-to-one relationship, one object is connected to only one object from another model. For example, one user can have one profile.

Note: OneToOneField is useful when you want to store additional information separately while keeping exactly one related record.

1. What is OneToOneField?

OneToOneField creates a one-to-one relationship between two Django models.

For example:

User
  ↓
Profile

One User can have one Profile, and that Profile belongs to one User.

2. Why Use OneToOneField?

OneToOneField is useful when additional information needs to be stored in a separate model.

  • Separate related information into another model.
  • Maintain a one-to-one connection.
  • Extend an existing model with additional data.
  • Keep models organized.
  • Represent real-world one-to-one relationships.

3. Basic OneToOneField Syntax

The basic syntax is:

field_name = models.OneToOneField(
    ModelName,
    on_delete=models.CASCADE
)

The first argument specifies the related model.

4. Creating a User Model

Suppose we have a simple User model:

from django.db import models

class User(models.Model):

    name = models.CharField(
        max_length=100
    )

    email = models.EmailField()

This model stores basic user information.

5. Creating a Profile Model

We can connect a Profile model to User using OneToOneField.

class Profile(models.Model):

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )

    phone = models.CharField(
        max_length=20
    )

Each Profile is connected to one User.

6. Understanding One-to-One Relationship

Suppose there are three users:

Rahul  → Profile 1
Aman   → Profile 2
Priya  → Profile 3

Each User has one corresponding Profile.

The same Profile cannot normally be assigned to multiple User objects through this OneToOneField.

7. OneToOneField vs ForeignKey

Field Relationship Example
ForeignKey Many-to-One Many Students → One Course
OneToOneField One-to-One One User → One Profile

The main difference is the number of related objects allowed.

8. Understanding on_delete

The on_delete argument determines what happens to the related Profile when the referenced User is deleted.

user = models.OneToOneField(
    User,
    on_delete=models.CASCADE
)

Different deletion behaviors can be selected according to the application's requirements.

9. CASCADE with OneToOneField

With CASCADE, deleting the referenced User can also delete its related Profile.

user = models.OneToOneField(
    User,
    on_delete=models.CASCADE
)

This is common when the Profile should not exist without its User.

10. PROTECT with OneToOneField

PROTECT prevents deletion of the referenced User when the related Profile exists.

user = models.OneToOneField(
    User,
    on_delete=models.PROTECT
)

This can be useful when the related record must remain protected.

11. SET_NULL with OneToOneField

SET_NULL sets the relationship to NULL when the referenced object is deleted.

user = models.OneToOneField(
    User,
    null=True,
    on_delete=models.SET_NULL
)

The field must allow NULL values.

12. Creating a User Object

First create a User object:

user = User.objects.create(
    name="Rahul",
    email="rahul@example.com"
)

This User can then be connected to a Profile.

13. Creating a Profile

Create a Profile and assign the User object:

profile = Profile.objects.create(
    user=user,
    phone="9876543210"
)

The Profile is now connected to the User.

14. Accessing the Related Profile

After retrieving a User, you can access its Profile using the reverse relationship.

user = User.objects.get(
    id=1
)

print(user.profile.phone)

The default reverse accessor is based on the related model name.

15. Accessing the User from Profile

The Profile can directly access its related User.

profile = Profile.objects.get(
    id=1
)

print(profile.user.name)
print(profile.user.email)

The user field points to the related User object.

16. Using related_name

You can customize the reverse relationship using related_name.

user = models.OneToOneField(
    User,
    on_delete=models.CASCADE,
    related_name="profile"
)

Now the User can access the Profile using:

user.profile

17. OneToOneField and Unique Records

A OneToOneField ensures that the relationship is unique. A related object cannot normally be associated with multiple objects on the other side.

class Profile(models.Model):

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )

This is different from a ForeignKey, where multiple records can reference the same object.

18. Querying with OneToOneField

You can query Profile objects using fields from the related User model.

profiles = Profile.objects.filter(
    user__name="Rahul"
)

The double underscore allows Django to traverse the relationship.

19. Filtering by Related User ID

You can filter profiles using the related User ID.

profiles = Profile.objects.filter(
    user_id=1
)

This returns the Profile associated with User ID 1, if it exists.

20. OneToOneField in Templates

One-to-one related data can be displayed directly in a Django template.

<h3>{{ user.name }}</h3>

<p>
Email: {{ user.email }}
</p>

<p>
Phone: {{ user.profile.phone }}
</p>

Django follows the relationship using dot notation.

21. OneToOneField in a View

A view can retrieve a User and display its Profile.

from django.shortcuts import render
from .models import User

def profile(request):

    user = User.objects.get(
        id=1
    )

    return render(
        request,
        "profile.html",
        {"user": user}
    )

The template can then access the related profile.

22. select_related() with OneToOneField

select_related() can be used with OneToOneField to retrieve related objects efficiently.

profiles = Profile.objects.select_related(
    "user"
).all()

This is useful when displaying many profiles together with user information.

23. OneToOneField with ModelForm

A ModelForm can include a OneToOneField.

from django import forms
from .models import Profile

class ProfileForm(forms.ModelForm):

    class Meta:
        model = Profile

        fields = [
            "user",
            "phone"
        ]

Django generates the appropriate form field for selecting the related User.

24. Extending a User with a Profile

One common use of OneToOneField is to store additional information in a separate Profile model.

class Profile(models.Model):

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )

    phone = models.CharField(
        max_length=20
    )

    address = models.TextField()

    date_of_birth = models.DateField(
        null=True,
        blank=True
    )

The Profile can contain information that is separate from the User model.

25. Creating a Profile for an Existing User

You can create a Profile for an existing User:

user = User.objects.get(
    id=1
)

Profile.objects.create(
    user=user,
    phone="9876543210"
)

The Profile is connected to that specific User.

26. Checking Whether a Profile Exists

When using a reverse one-to-one relationship, the related object may not exist. You should handle that situation appropriately.

try:

    profile = user.profile

except Profile.DoesNotExist:

    profile = None

This prevents an exception from stopping the application when the Profile has not been created.

27. OneToOneField and Migrations

After creating or modifying a OneToOneField, run migrations.

python manage.py makemigrations

python manage.py migrate

Django uses migrations to apply model changes to the database.

28. Complete OneToOneField Example

from django.db import models


class User(models.Model):

    name = models.CharField(
        max_length=100
    )

    email = models.EmailField()

    def __str__(self):
        return self.name


class Profile(models.Model):

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name="profile"
    )

    phone = models.CharField(
        max_length=20
    )

    address = models.TextField(
        blank=True
    )

    def __str__(self):
        return self.user.name

In this example, every Profile belongs to one User, and each User can have one related Profile.

29. Common OneToOneField Mistakes

  • Confusing OneToOneField with ForeignKey.
  • Forgetting the on_delete argument.
  • Forgetting to run migrations.
  • Trying to create multiple Profiles for the same User.
  • Not handling a missing reverse relationship.
  • Using an incorrect related field name.
  • Deleting a User without considering CASCADE behavior.
  • Making unnecessary database queries when loading related objects.

30. OneToOneField Summary

OneToOneField is used when one object should be connected to exactly one object from another model.

  • It creates a one-to-one relationship.
  • One User can have one Profile.
  • The related object can access its parent through the relationship field.
  • The reverse relationship can be customized with related_name.
  • on_delete controls deletion behavior.
  • Double underscores can be used to query related fields.
  • select_related() can optimize one-to-one queries.
  • Model changes require migrations.
  • OneToOneField is useful for extending models with additional information.

📌 Key Points

  • OneToOneField creates a one-to-one relationship.
  • It is commonly used for User and Profile relationships.
  • Each related object can have only one corresponding object on the other side.
  • on_delete controls what happens when the referenced object is deleted.
  • related_name customizes reverse relationship access.
  • Double-underscore syntax can be used to query related fields.
  • select_related() can efficiently load one-to-one related objects.
  • Always run migrations after changing relationship fields.

🧠 Quick Quiz

Question: Which Django field is used to create a one-to-one relationship?