← Назад к вопросам

Что такое OneToOneField в Django?

1.3 Junior🔥 131 комментариев
#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

OneToOneField в Django: Полное Руководство

OneToOneField — это тип отношения в Django ORM, который устанавливает уникальную связь один-к-одному между двумя моделями. Это означает, что каждому экземпляру одной модели соответствует ровно один экземпляр другой модели, и наоборот.

Основная Синтаксис

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.TextField()
    avatar = models.ImageField(upload_to='avatars/')
    phone = models.CharField(max_length=20)

В этом примере каждый User имеет ровно один UserProfile, и каждый профиль привязан к одному пользователю.

Параметр on_delete

Обязательный параметр, определяющий поведение при удалении связанного объекта:

# CASCADE — удалить объект при удалении связанного
user = models.OneToOneField(User, on_delete=models.CASCADE)

# SET_NULL — установить NULL (поле должно быть null=True)
user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True)

# SET_DEFAULT — установить значение по умолчанию
user = models.OneToOneField(User, on_delete=models.SET_DEFAULT, default=1)

# SET() — установить функцию или значение
user = models.OneToOneField(User, on_delete=models.SET(get_sentinel_user))

# PROTECT — предотвратить удаление (вызвать ProtectedError)
user = models.OneToOneField(User, on_delete=models.PROTECT)

# DO_NOTHING — не делать ничего (может привести к проблемам БД)
user = models.OneToOneField(User, on_delete=models.DO_NOTHING)

Доступ к Данным

Django автоматически создает обратные ссылки, позволяя получать доступ к связанному объекту с обеих сторон:

# Прямой доступ (от профиля к пользователю)
profile = UserProfile.objects.get(id=1)
user_name = profile.user.name

# Обратный доступ (от пользователя к профилю)
user = User.objects.get(id=1)
bio = user.userprofile.bio  # имя модели в нижнем регистре

Кастомизация Обратной Ссылки

Можно изменить имя обратной ссылки с помощью параметра related_name:

class UserProfile(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name='profile'  # теперь доступно как user.profile
    )
    bio = models.TextField()

# Использование
user = User.objects.get(id=1)
bio = user.profile.bio  # вместо user.userprofile.bio

Различие от ForeignKey

ForeignKey позволяет многим объектам одной модели ссылаться на один объект другой модели (многие-к-одному), а OneToOneField гарантирует уникальность с обеих сторон:

# ForeignKey: много комментариев — один пост
class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    text = models.TextField()

# OneToOneField: один профиль — один пользователь
class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

Практические Примеры

Расширение встроенной User модели

from django.contrib.auth.models import User

class UserExtendedProfile(models.Model):
    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name='extended_profile'
    )
    company = models.CharField(max_length=100, blank=True)
    job_title = models.CharField(max_length=100, blank=True)
    bio = models.TextField(blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f\"{self.user.username}'s Profile\"

Сигналы для автоматического создания профиля

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserExtendedProfile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.extended_profile.save()

Заключение

OneToOneField в Django — это мощный инструмент для моделирования отношений один-к-одному. Он часто используется для расширения встроенных моделей, создания дополнительных профилей пользователей и моделирования уникальных связей между сущностями. Правильное использование параметров и обратных ссылок делает код более чистым и поддерживаемым.

Что такое OneToOneField в Django? | PrepBro