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

Функция prefetch_related_objects

Функция prefetch_related_objects применяется к существующему списку моделей и выполняет превентивную подгрузку связанных объектов для каждого элемента списка. Это позволяет избежать проблемы "N+1 запросов", когда для каждого объекта выполняется отдельный запрос для получения связанных данных. Функция принимает список моделей и аргументы для указания связей, которые необходимо предзагрузить.

Синтаксис

from django.db.models import prefetch_related_objects prefetch_related_objects(objects, *lookups)

Параметры функции:

objects - итерируемый объект с моделями (QuerySet или список), для которых нужно предзагрузить связанные данные.

*lookups - один или несколько аргументов, определяющих связи для превентивной загрузки. Это могут быть строки с именами полей связи или объекты Prefetch для более тонкой настройки.

Пример

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

from django.db import models from django.db.models import prefetch_related_objects class Author(models.Model): name = models.CharField(max_length=100) class Article(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE) # Получаем все статьи articles = list(Article.objects.all()) # Предзагружаем авторов для всех статей prefetch_related_objects(articles, 'author') for article in articles: print(f"Article: {article.title}, Author: {article.author.name}")

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

"Article: Django basics, Author: John Doe" "Article: Advanced ORM, Author: Jane Smith" "Article: Web development, Author: John Doe"

Пример

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

from django.db import models from django.db.models import prefetch_related_objects class Profile(models.Model): bio = models.TextField() author = models.OneToOneField(Author, on_delete=models.CASCADE) class Article(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey(Author, on_delete=models.CASCADE) tags = models.ManyToManyField('Tag') class Tag(models.Model): name = models.CharField(max_length=50) # Получаем недавние статьи articles = list(Article.objects.filter(title__icontains='django')) # Предзагружаем авторов и профили авторов prefetch_related_objects(articles, 'author__profile') for article in articles: print(f"Article: {article.title}") print(f"Author: {article.author.name}") print(f"Bio: {article.author.profile.bio}") print("---")

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

"Article: Django basics" "Author: John Doe" "Bio: Senior developer with 10 years of experience" "---" "Article: Django advanced" "Author: Jane Smith" "Bio: Python expert and Django core contributor" "---"

Пример

Использование функции с объектом Prefetch для дополнительной фильтрации и сортировки подгружаемых данных:

from django.db import models from django.db.models import prefetch_related_objects, Prefetch, Q class Comment(models.Model): text = models.TextField() article = models.ForeignKey(Article, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) is_approved = models.BooleanField(default=True) # Получаем статьи articles = list(Article.objects.all()) # Создаем Prefetch объект для подгрузки только одобренных комментариев prefetch_comments = Prefetch( 'comment_set', queryset=Comment.objects.filter(is_approved=True).order_by('-created_at'), to_attr='approved_comments' ) # Применяем превентивную загрузку prefetch_related_objects(articles, prefetch_comments) for article in articles: print(f"Article: {article.title}") print(f"Comments count: {len(article.approved_comments)}") for comment in article.approved_comments[:3]: print(f" - {comment.text}") print("---")

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

"Article: Django basics" "Comments count: 5" " - Great article!" " - Very helpful, thanks!" " - Could you explain more about models?" "---" "Article: Advanced ORM" "Comments count: 3" " - This is exactly what I needed" " - Excellent explanation" " - Helped me optimize my queries" "---"

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

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