Поле OneToOneField

Поле OneToOneField определяет отношение один-к-одному между двумя моделями. Каждая запись одной модели связана ровно с одной записью другой модели. Это поле часто используется для расширения существующей модели, добавляя дополнительные атрибуты, без изменения исходной модели. Поле принимает обязательный аргумент - модель, с которой устанавливается связь, а также ряд дополнительных параметров, таких как on_delete, related_name и parent_link.

Синтаксис

pythonfield_name = models.OneToOneField(
  to, 
  on_delete=models.CASCADE,
  related_name=None,
  parent_link=False,
  **options
)

Пример . Модель

Рассмотрим пример использования OneToOneField для расширения стандартной модели пользователя:

pythonfrom django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
  user = models.OneToOneField(
    User, 
    on_delete=models.CASCADE,
    related_name='profile'
  )
  bio = models.TextField(blank=True)
  birth_date = models.DateField(null=True, blank=True)
  avatar = models.ImageField(upload_to='avatars/', blank=True)

  def __str__(self):
    return f"Profile of {self.user.username}"

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

Пример . Создание связанных объектов

Создадим пользователя и его профиль:

pythonfrom django.contrib.auth.models import User
from myapp.models import Profile

# Создаем пользователя
user = User.objects.create_user(
  username='john_doe',
  password='secret123'
)

# Создаем профиль для пользователя
profile = Profile.objects.create(
  user=user,
  bio='Django developer',
  birth_date='1995-06-15'
)

print(f"User: {user.username}")
print(f"Profile bio: {profile.bio}")

Результат выполнения кода:

python"User: john_doe"
"Profile bio: Django developer"

Пример . Доступ к связанным объектам

Получим профиль пользователя и пользователя через профиль:

pythonfrom django.contrib.auth.models import User
from myapp.models import Profile

# Доступ к профилю через пользователя
user = User.objects.get(username='john_doe')
profile = user.profile
print(f"User bio: {profile.bio}")

# Доступ к пользователю через профиль
profile = Profile.objects.get(bio='Django developer')
user = profile.user
print(f"Profile user: {user.username}")

Результат выполнения кода:

python"User bio: Django developer"
"Profile user: john_doe"

Пример . Использование select_related с OneToOneField

Для оптимизации запросов используйте select_related при выборке связанных данных:

pythonfrom myapp.models import Profile

# Запрос с предварительной загрузкой связанного пользователя
profiles = Profile.objects.select_related('user').all()
for profile in profiles:
  print(f"{profile.user.username}: {profile.bio}")

Результат выполнения кода:

python"john_doe: Django developer"

Смотрите также

  • поле ForeignKey,
    которое создает связь один-ко-многим между моделями
  • поле ManyToManyField,
    которое создает связь многие-ко-многим между моделями
  • метод select_related,
    который оптимизирует выборку связанных объектов
  • метод prefetch_related,
    который оптимизирует выборку для связей многие-ко-многим