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="Я люблю Django!")

Або при використанні пов'язаного імені related_name:

# Створюємо профіль через зворотний зв'язок
user.profile = Profile(bio="Захоплений учень Django")
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="Моя перша стаття")

Ми також можемо додати статтю через зворотний зв'язок:

# Використовуємо related_name для додавання статті
author.articles.create(title="Друга стаття")

🛠 Примітка:

Якщо related_name не задано, за замовчуванням буде використовуватися <ім'я_моделі>_set:

author.article_set.create(title="Третя стаття")

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)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Олександр Рівень 83
11 вересня 2025
Останній приклад: " # Перевіряємо зв'язок із книгами print(Reader.objects.get(name="John Doe").books_read.all()) # книги залишаться " У цьому випадку книги НЕ залишаться, а будуть видалені!