Сущности предметной области существуют не сами по себе. Они часто зависят друг от друга. На уровне базы данных такие связи задаются через внешние ключи или даже промежуточные таблицы, как в случае связи "многие ко многим". ORM, в свою очередь, используют эти ключи для работы со связями, а также добавляют множество полезных методов, которые упрощают работу с зависимыми сущностями: выборкой, добавлением, модификацией и удалением.
Учебный проект моделирует предметную область системы для ведения персональных блогов. Сейчас нам интересна модель Post — модель записи (поста) в блоге. Пользователи (модель User
) связаны с постами "один ко многим":
- Один пользователь может быть автором множества постов
- У каждого поста всегда один автор
Описание связи между моделями
Для того, чтобы связать пост и автора, было использовано поле типа ForeignKey
, которое в терминах баз данных представляет собой внешний ключ. Ниже соответствующий фрагмент:
class User(models.Model):
"""A blog user."""
# ...
class Post(models.Model):
"""A blog post."""
# ...
creator = models.ForeignKey(User, on_delete=models.CASCADE)
# ...
Такого описания достаточно для Django ORM: он будет знать, какие запросы следует сделать в БД, чтобы при обращении к полю creator
экземпляра модели Post
вы получали уже экземпляр пользователя. При этом ORM экономит ресурсы системы и по умолчанию не пытается получить сразу все возможные данные: пока вы не запросите доступ к автору поста, автор не будет запрошен из базы!
Опция
on_delete=models.Cascade
описана ниже.
Создание связей между объектами
При создании объекта модели, имеющей внешний ключ, в качестве значения поля обычно указывают уже созданный (сохранённый в БД) экземпляр другой модели. Такое возможно, например, при создании объектов с помощью менеджера — вы можете даже создавать несколько связанных объектов в одном выражении:
Post.objects.create(
title="Intro",
body="Hi, my name is Bob!",
creator=User.objects.create(
email="bob@blogs.org",
first_name="Bob",
last_name="Smith",
)
)
# INSERT INTO "blog_user" ...