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

Атрибут to_attr

Атрибут to_attr применяется к экземпляру класса Prefetch и позволяет задать пользовательское имя атрибута, в который будут сохранены результаты предварительной загрузки связанных объектов. В отличие от стандартного поведения prefetch_related, где связанные объекты добавляются к родительской модели под тем же именем, что и поле отношения, использование to_attr дает возможность явно управлять именами атрибутов. Это особенно полезно при работе с несколькими Prefetch объектами для одной и той же связи или при необходимости загрузить связанные объекты с дополнительными условиями фильтрации.

Синтаксис

from django.db import models from django.db.models import Prefetch queryset = Model.objects.prefetch_related( Prefetch('related_field', queryset=RelatedModel.objects.all(), to_attr='custom_name') )

Пример . С моделью Category и Article

Рассмотрим модели Category и Article, где у категории может быть много статей. Используем to_attr, чтобы сохранить все статьи категории в атрибут 'articles_list':

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) category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='articles') is_published = models.BooleanField(default=True) def __str__(self): return self.title

Теперь выполним запрос с использованием Prefetch и атрибута to_attr:

from myapp.models import Category from myapp.models import Article from django.db.models import Prefetch prefetch = Prefetch('articles', queryset=Article.objects.filter(is_published=True), to_attr='published_articles') categories = Category.objects.prefetch_related(prefetch) for category in categories: print(f"Category: {category.name}") for article in category.published_articles: print(f" - {article.title}")

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

"Category: Technology" " - Django Basics" " - Python Tips" "Category: Science" " - Quantum Physics"

Пример . С множественными Prefetch

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

from myapp.models import Category from myapp.models import Article from django.db.models import Prefetch published = Prefetch('articles', queryset=Article.objects.filter(is_published=True), to_attr='published_articles') drafts = Prefetch('articles', queryset=Article.objects.filter(is_published=False), to_attr='draft_articles') categories = Category.objects.prefetch_related(published, drafts) for category in categories: print(f"Category: {category.name}") print(f" Published: {len(category.published_articles)}") print(f" Drafts: {len(category.draft_articles)}")

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

"Category: Technology" " Published: 2" " Drafts: 1" "Category: Science" " Published: 1" " Drafts: 0"

Пример . С использованием только to_attr

Атрибут to_attr можно использовать самостоятельно, без указания дополнительных фильтров в queryset:

from myapp.models import Category from myapp.models import Article from django.db.models import Prefetch prefetch = Prefetch('articles', to_attr='all_articles') categories = Category.objects.prefetch_related(prefetch) for category in categories: print(f"{category.name}: {len(category.all_articles)} articles")

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

"Technology: 3 articles" "Science: 1 articles"

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

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