Что такое поле ForeignKey в Django ORM?

Ответ

В Django ORM, ForeignKey — это тип поля модели, который устанавливает связь «многие-к-одному» (many-to-one) между двумя моделями. Это означает, что один объект текущей модели может быть связан только с одним объектом другой модели, но один объект другой модели может быть связан со множеством объектов текущей модели. Это фундаментальный механизм для построения реляционных связей в базе данных, обеспечивающий целостность данных и предотвращающий их дублирование.

Пример:

from django.db import models

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

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE) # Связь с моделью Author

    def __str__(self):
        return self.title

В этом примере, каждая Book связана с одним Author через поле author. Параметр on_delete является обязательным и определяет поведение при удалении связанного объекта Author. models.CASCADE означает, что при удалении автора будут удалены и все связанные с ним книги. Другие распространённые варианты: models.PROTECT, models.SET_NULL, models.SET_DEFAULT, models.DO_NOTHING.

Ключевые особенности:

  • Реляционная связь: Создает связь «многие-к-одному» на уровне базы данных.
  • Индексирование: Автоматически создает индекс в базе данных для поля ForeignKey, что ускоряет операции JOIN.
  • Первичный ключ: По умолчанию ссылается на первичный ключ (id) связанной модели.
  • Обратный доступ (related_name): Позволяет получить доступ к связанным объектам в обратном направлении. Например, если не указан related_name, можно получить все книги автора через author_instance.book_set.all(). Если указать related_name='books', то author_instance.books.all().
  • Целостность данных: Обеспечивает ссылочную целостность, предотвращая создание "висячих" ссылок.

Ответ 18+ 🔞

А, ну вот, ForeignKey, блядь! Это ж та самая штука, когда один к одному, а на самом деле — один ко многим, ёпта! Ну, типа, представь себе: есть у тебя автор, один такой, с бородой и в очках, а книг у него — овердохуища, целая куча! Вот эта связь и есть ForeignKey, сука!

Смотри, как это работает, на примере, а то мозги сейчас нахуй улетят:

from django.db import models

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

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE) # Вот она, сука, связь!

    def __str__(self):
        return self.title

Видишь? Каждая книжка (Book) знает своего папашу-автора (Author) через это поле author. А вот on_delete — это, блядь, очень важная штука! Это как инструкция на случай, если автор вдруг решит на тот свет податься. CASCADE — значит, если автор сдох (удалили запись), то и все его книжки — в пизду, следом за ним полетят. Жестоко, но честно.

А есть и другие варианты, типа:

  • PROTECT — не даст удалить автора, пока у него книжки есть, будет орать как резаный.
  • SET_NULL — автор удалился, а у книжек в поле author просто будет NULL, пустота, блядь.
  • SET_DEFAULT — подставит какого-то дефолтного автора, типа "Неизвестен".
  • DO_NOTHING — это вообще пиздец, ни хуя не делать, пусть база данных сама разбирается, обычно так не делают, а то потом висячие ссылки будут, как срам.

Что ещё важно, блядь:

  • Связь в базе: На самом деле в таблице Book появится колонка author_id, которая тыкает пальцем в запись в таблице Author. Это и есть магия.
  • Индекс: Оно само, сука, индекс создаст, чтобы JOIN-ы быстрее летали. Умная штука.
  • Обратный доступ: А вот это вообще прикол! Если не париться, то от автора ко всем его книжкам можно достучаться так: tolstoy.book_set.all(). А если в ForeignKey дописать related_name='books', то уже можно как царь: tolstoy.books.all(). Красота, в рот меня чих-пых!
  • Целостность: Главное, что не получится записать в author_id какую-то левую хуйню, которой нет в таблице авторов. База не даст, будет материться на тебя.

Вот и весь сказ, блядь. ForeignKey — это как верёвочка, которая привязывает кучу книжек к одной ноге автора, чтобы не разбежались.