Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

2.4 Связь Many-to-Many (Многие ко многим)
2 из 2 шагов пройдено

Введение в отношения «многие-ко-многим» в Django

В отношении «многие-ко-многим» несколько строк в таблице связаны с несколькими строками в другой таблице. Обе модели здесь выступают как равноправные, и определить, какая из них первичная, а какая вторичная, не представляется возможным.

Например, у сотрудника может быть несколько зарплатных программ, и каждая зарплатная программа может принадлежать нескольким сотрудникам.

Если нас есть зарплатные программы: "оклад", "бонусы", "проценты от дохода", то у каждого сотрудника их может быть несколько.

Таким образом, несколько строк в таблице сотрудников связаны с несколькими строками в таблице зарплат. Следовательно, отношения между работниками и компенсационными программами являются отношениями «многие-ко-многим».

Как правило, реляционные базы данных не реализуют прямую связь «многие-ко-многим» между двумя таблицами. Вместо этого они использует третью таблицу, таблицу соединения, для установления двух отношений «один-ко-многим» между двумя таблицами и таблицей соединения.

Следующая диаграмма иллюстрирует отношения «многие-ко-многим» в базе данных между таблицами hr_employee и hr_compensation:

Таблица hr_employee_compensations является соединительной. Она имеет два внешних ключа employee_id  и  compensation_id.

Внешний employee_id ключ ссылается на id таблицу hr_employee, а compensation_id внешний ключ ссылается id на hr_compensation таблицу.

Как правило, вам не нужен id столбец в hr_employee_compensations таблице в качестве первичного ключа , и вы можете использовать оба employee_id и compensation_id в качестве составного первичного ключа. Однако Django всегда создает id столбец в качестве первичного ключа для таблицы соединения.

Кроме того, Django создает уникальное ограничение , включающее столбцы employee_id и compensation_id. Другими словами, в таблице не будет повторяющихся пар employee_id и compensation_id значений hr_employee_compensations.

Чтобы создать отношения «многие-ко-многим» в Django, вы используете файл ManyToManyField. Доработаем нашу модель, добавив ManyToManyField для создания отношения «многие-ко-многим» между моделями Employee и Compensation:

from django.db import models


class Compensation(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class Contact(models.Model):
    phone = models.CharField(max_length=50, unique=True)
    address = models.CharField(max_length=50)

    def __str__(self):
        return self.phone


class Department(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)

    def __str__(self):
        return self.name


class Employee(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    contact = models.OneToOneField(Contact, on_delete=models.CASCADE, null=True)
    department = models.ForeignKey(Department, on_delete=models.CASCADE, default=None)
    compensations = models.ManyToManyField(Compensation)

    def __str__(self):
        return f'{self.first_name} {self.last_name}'

Поле compensations использует ManyToManyField для установления отношения «многие-ко-многим» между классами Employee и Compensation.

Выполним миграции и посмотрим нашу базу данных:

python manage.py makemigrations
python manage.py migrate

Как мы видим Django создал две новые таблицы hr_compensation и таблицу соединений hr_employee_compensations следующим образом:

В следующем шаге начнем работать с запросами с данным типом отношений.


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