РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
43 of 818 menu

Поле ForeignKey

Поле ForeignKey применяется для установления связи между двумя моделями, где одной записи родительской модели может соответствовать множество записей дочерней модели. Поле принимает обязательный аргумент - класс связанной модели, а также поддерживает дополнительные параметры, такие как on_delete, определяющий поведение при удалении связанной записи, related_name для обратной связи и другие. Связи через ForeignKey позволяют выполнять запросы как от родителя к дочерним записям, так и в обратную сторону.

Синтаксис

from django.db import models class ChildModel(models.Model): parent = models.ForeignKey(ParentModel, on_delete=models.CASCADE)

Пример

Давайте создадим две модели: Category и Article, где каждая статья принадлежит одной категории:

from django.db import models class Category(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() category = models.ForeignKey(Category, on_delete=models.CASCADE) def __str__(self): return self.title

Пример

Теперь создадим категорию и несколько статей, связанных с этой категорией:

from myapp.models import Category, Article # Create a category category = Category.objects.create(name="Programming") # Create articles belonging to this category article1 = Article.objects.create( title="Django Basics", content="Introduction to Django", category=category ) article2 = Article.objects.create( title="Advanced Django", content="Deep dive into Django", category=category ) print(article1.category.name) print(article2.category.name)

Результат выполнения кода:

"Programming" "Programming"

Пример

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

from myapp.models import Category category = Category.objects.get(name="Programming") articles = category.article_set.all() for article in articles: print(article.title)

Результат выполнения кода:

"Django Basics" "Advanced Django"

Пример

Используем параметр related_name для задания более удобного имени обратной связи:

from django.db import models class Category(models.Model): name = models.CharField(max_length=100) class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() category = models.ForeignKey( Category, on_delete=models.CASCADE, related_name="articles" )

Теперь обращаться к статьям категории можно через имя articles:

from myapp.models import Category category = Category.objects.get(name="Programming") articles = category.articles.all() for article in articles: print(article.title)

Результат выполнения кода:

"Django Basics" "Advanced Django"

Пример

Рассмотрим параметр on_delete, который определяет поведение при удалении связанного объекта. Используем models.CASCADE для автоматического удаления всех дочерних записей:

from myapp.models import Category, Article category = Category.objects.get(name="Programming") # Delete category - all related articles will be deleted automatically category.delete() # Check that articles are deleted articles_count = Article.objects.filter(category=category).count() print(articles_count)

Результат выполнения кода:

"0"

Пример

Используем параметр on_delete=models.PROTECT, который запрещает удаление категории, если к ней привязаны статьи:

from django.db import models class Category(models.Model): name = models.CharField(max_length=100) class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() category = models.ForeignKey( Category, on_delete=models.PROTECT )

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

from myapp.models import Category category = Category.objects.get(name="Programming") try: category.delete() except Exception as e: print(str(e))

Результат выполнения кода:

"Cannot delete some instances of model 'Category' because they are referenced through protected foreign key"

Смотрите также

  • поле ManyToManyField,
    которое создает связь многие-ко-многим между моделями
  • поле OneToOneField,
    которое создает связь один-к-одному между моделями
  • метод select_related,
    который оптимизирует запросы с внешними ключами
  • метод prefetch_related,
    который оптимизирует запросы с обратными связями
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить