JavaRush /Курсы /Модуль 3: Django /Создание и удаление связанных объектов

Создание и удаление связанных объектов

Модуль 3: Django
9 уровень , 5 лекция
Открыта

На предыдущих лекциях мы изучили основные виды связей между моделями: OneToOne, ForeignKey и ManyToMany.

Сегодня мы идём дальше и сосредоточимся на том, как создавать и удалять объекты с использованием этих связей.

🌱 Создание связанных объектов

Когда один объект связан с другим, зачастую нам требуется создать этот связанный объект "на месте" или связать уже существующий объект. Django предоставляет несколько подходов для работы с этим, в зависимости от типа связи.

1. Создание связанных объектов с OneToOne

Связь один-к-одному означает, что один объект может быть связан только с одним другим. Пример из жизни: у каждого пользователя может быть только один персональный профиль.

Давайте создадим две модели: User и Profile.

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=100)

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    bio = models.TextField()

Теперь, если мы хотим создать профиль для пользователя, мы можем сделать это следующим образом:

# Создаём пользователя
user = User.objects.create(username="student")

# Создаём связанный профиль
profile = Profile.objects.create(user=user, bio="I love Django!")

Или при использовании связанного имени related_name:

# Создаём профиль через обратную связь
user.profile = Profile(bio="Enthusiastic Django learner")
user.profile.save()

🛠 Особенность:

Если вы попытаетесь создать второй профиль для одного и того же пользователя, Django выбросит ошибку, ведь связь OneToOne не допускает дублирования.

2. Создание объектов с ForeignKey

Связь "один-ко-многим" используется, когда один объект может быть связан со многими другими. Например, каждый пользователь может иметь несколько статей.

class Article(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='articles')
    title = models.CharField(max_length=200)

Создание статьи с уже существующим автором:

author = User.objects.create(username="author_username")
article = Article.objects.create(author=author, title="My First Article")

Мы также можем добавить статью через обратную связь:

# Используем related_name для добавления статьи
author.articles.create(title="Second Article")

🛠 Примечание:

Если related_name не задано, по умолчанию будет использоваться <имя_модели>_set:

author.article_set.create(title="Third Article")

3. Создание объектов с ManyToMany

Связь "многие-ко-многим" идеально подходит для случаев, когда объекты могут быть связаны с несколькими другими. Например, студенты посещают курсы, и каждый курс имеет много студентов.

class Course(models.Model):
    name = models.CharField(max_length=200)

class Student(models.Model):
    name = models.CharField(max_length=100)
    courses = models.ManyToManyField(Course, related_name='students')

Создание объектов и связывание их:

# Создаём студента и курс
student = Student.objects.create(name="Alice")
course = Course.objects.create(name="Django Masterclass")

# Связываем их
student.courses.add(course)

Мы также можем сразу связать объект при его создании:

# Создаём курс и сразу связываем с существующим студентом
new_course = Course.objects.create(name="Python Basics")
student.courses.add(new_course)

# Или создаём студента и привязываем к курсу
course.students.create(name="Bob")

🛠 Особенность:

метод add() поддерживает множественные добавления:

student.courses.add(course1, course2, course3)

🗑 Удаление связанных объектов

Удаление связано с вопросом: "А что делать с зависимыми объектами?". Ответ Django — это выбор поведения через on_delete для ForeignKey и OneToOneField.

1. Удаление объектов с OneToOne

Если пользователь удаляется, логично, что профиль тоже должен быть удалён. Это мы задаём с помощью on_delete=models.CASCADE.

Пример:

# Удалим пользователя
user.delete()

# Профиль будет автоматически удалён

Мы также можем вручную удалить профиль:

profile.delete()

2. Удаление объектов с ForeignKey

Представьте, что мы удаляем автора статьи. Что должно произойти? Установленное значение on_delete определяет поведение:

  • CASCADE — статьи автора будут удалены.
  • SET_NULL — автор для статьи станет NULL.
# Если автор удалён, связанные статьи тоже удаляются
author.delete()

Если вы используете SET_NULL, вам нужно разрешить значение NULL для поля author:

author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)

Теперь, при удалении автора, статьи останутся:

author.delete()
# Статьи останутся, но поле author станет NULL

3. Удаление объектов с ManyToMany

Удаление элементов из связи выполняется с помощью методов remove() и clear().

# Удаление конкретного курса у студента
student.courses.remove(course)

# Удаление всех курсов студента
student.courses.clear()

🛠 Особенности: если вы удаляете курс или студента, Django автоматически удаляет записи в промежуточной таблице student_courses.

🔨 Практическая часть: создаём учебное приложение

Представьте, что мы моделируем приложение для библиотек. У нас есть следующие сущности:

  1. Book (Книга)
  2. Author (Автор)
  3. Reader (Читатель)

Связи:

  • Один автор написал много книг ForeignKey.
  • Одна книга может быть прочитана многими читателями, а читатели читают много книг ManyToMany.

Модели:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')

class Reader(models.Model):
    name = models.CharField(max_length=100)
    books_read = models.ManyToManyField(Book, related_name='readers')

Попробуйте выполнить следующие шаги:

  1. Создайте автора и несколько книг, связанных с ним.
  2. Создайте читателя и свяжите его с несколькими книгами.
  3. Удалите автора и посмотрите, что произойдёт с книгами.
  4. Убедитесь, как работает удаление книг из связи с читателем.
# Пример:
author = Author.objects.create(name="J.K. Rowling")
book1 = Book.objects.create(title="Harry Potter and the Philosopher's Stone", author=author)
book2 = Book.objects.create(title="Harry Potter and the Chamber of Secrets", author=author)

reader = Reader.objects.create(name="John Doe")
reader.books_read.add(book1, book2)

# Удаляем автора
author.delete()

# Проверяем связь с книгами
print(Reader.objects.get(name="John Doe").books_read.all())  # книги останутся

Теперь вы умеете не только создавать связи, но и управлять ими в реальных проектах. Django ORM делает это максимально удобным! 😉

1
Задача
Модуль 3: Django, 9 уровень, 5 лекция
Недоступна
Работа с ManyToManyField: добавление и удаление связей
Работа с ManyToManyField: добавление и удаление связей
1
Задача
Модуль 3: Django, 9 уровень, 5 лекция
Недоступна
Работа с промежуточной таблицей через ForeignKey
Работа с промежуточной таблицей через ForeignKey
Комментарии (3)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
_den Уровень 64
23 ноября 2025
во второй задаче в admin.py добавлены модели Student и Course, если их не удалить проверка не будет работать
Дмитрий/MrJonson Уровень 90
23 сентября 2025
32 раза повторил проверку, ни чего не меняя ура прошло....
Дмитрий/MrJonson Уровень 90
23 сентября 2025
Вы когда нибудь приведете в порядок Вашу Конченную автопроверку заданий, Вторую задачу она вообще не принимает даже тот Вариант который Вы сами даете....