Типы связей между моделями ForeignKey, ManyToManyField, OneToOneField

Курс по Django: https://stepik.org/a/183363

Продолжаем совершенствовать наш учебный сайт и знакомиться с возможностями фреймворка Django. Начиная с этого занятия мы с вами разберемся с разными типами связей, которые можно устанавливать между таблицами БД. Но в начале, что это за связи и зачем они нужны и какие их типы поддерживаются фреймворком Django.

Давайте представим, что для каждой статьи дополнительно нужно хранить категорию, к которой она относится. Если бы мы при этом ограничивались только одной таблицей, то, очевидно, для указания категории статьи нам пришлось бы добавить еще одно поле с названием категории:

А теперь представьте, что нам потребовалось изменить название категории, например, вместо «Актриса» записать «Женщины актрисы». Тогда пришлось бы перебирать все записи и категории «Актриса» заменять на новое содержимое. Или требуется получить все записи только по актрисам. Тогда снова придется проходить по всей таблице и находить слова «Актриса» в поле category. Это, как вы понимаете, будет не самый быстрый процесс. Существует и много других недостатков такого подхода, когда все данные размещаются в одной таблице.

Чтобы ускорить извлечение данных, упростить их редактирование и многое другое, применяется подход разнесения данных по нескольким таблицам и установления связей между ними. Этот процесс получил название нормализации данных и составляет отдельный раздел знаний по базам данных. Мы его сейчас касаться не будем, так как у нас курс по Django и сосредоточимся на реализации этого механизма, а именно, на создании таблиц и установления между ними связей.

Итак, в нашем проекте, очевидно, нужно определить еще одну таблицу (модель) для категорий и связать ее с таблицей постов:

Для этого мы добавим еще одно поле cat_id в таблицу women, которое будет определено как внешний ключ и хранить идентификатор категории. А в таблице category определим поля: идентификатор id, название раздела и слаг. То есть, связь таблицы women с таблицей category выполняется с помощью целочисленного поля cat_id. Но какой тип связи здесь будет создан? Это зависит от того, какой класс фреймворка Djnago будет использован для организации связи. Они могут быть следующими:

  • ForeignKey – для связей Many to One (многие к одному);
  • ManyToManyField – для связей Many to Many (многие ко многим);
  • OneToOneField – для связей One to One (один к одному).

Чаще всего на практике используется отношение многие к одному (ForeignKey) и оно подходит для нашего примера, когда несколько постов имеют одну категорию и одна категория может быть связана с множеством постов:

Тип связи Many To One

Другой тип связи Many To Many подходит, например, для описания взаимосвязей между студентами и преподавателями. Очевидно, у каждого студента имеется множество преподавателей и у каждого преподавателя множество студентов. Такой тип связи реализуется через вспомогательную промежуточную таблицу по следующей схеме:

Тип связи Many To Many

Наконец, третий тип связи One To One (один к одному) хорошо подходит, например, для описания взаимосвязи между гражданином и его персональными данными. В частности, так можно связать ИНН с конкретным человеком и, очевидно, у каждого лица в РФ имеется только один ИНН и, соответственно, один ИНН может быть связан только с одним гражданином. То же самое касается и паспортных данных. Правда, загран паспортов может быть несколько у одного лица, и здесь связь один к одному уже не подходит.

Тип связи One To One

Подробнее о классах разных типов связей можно почитать на следующей странице документации:

https://docs.djangoproject.com/en/4.2/ref/models/fields/#module-django.db.models.fields.related

На ближайших занятиях мы с вами подробнее познакомимся со всеми тремя типами связей. А начнем с самой распространенной Many-To-One, которая хорошо подходит для реализации категорий наших постов. Но сделаем это уже на следующем занятии.

Курс по Django: https://stepik.org/a/183363

Видео по теме