Метод defer

Метод defer применяется к QuerySet и возвращает новый QuerySet, который не загружает указанные поля модели при выполнении запроса. Вместо этого Django загрузит эти поля позднее, при первом обращении к ним. Это позволяет уменьшить объем данных, передаваемых из базы данных, и ускорить выполнение запросов, особенно когда в модели много полей, но вам нужны только некоторые из них. Метод принимает имена полей в качестве аргументов и может быть вызван цепочкой.

Синтаксис

pythonModel.objects.defer(*field_names)

Пример

Рассмотрим модель Article с большим текстовым полем. Отложим загрузку этого поля:

pythonfrom myapp.models import Article

# Defer loading of the 'content' field
articles = Article.objects.defer('content')
for article in articles:
  # Accessing the 'title' field does not cause an extra query
  print(article.title)
  # Accessing the 'content' field triggers an additional query
  print(article.content)

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

python"First Article"
"Content of the first article"
"Second Article"
"Content of the second article"

Пример

Отложим загрузку сразу нескольких полей модели User:

pythonfrom myapp.models import User

# Defer loading of 'bio' and 'avatar' fields
users = User.objects.defer('bio', 'avatar')
for user in users:
  print(user.username)
  # When accessing 'bio', Django loads it from the database
  if user.bio:
    print(user.bio)

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

python"john_doe"
"Software developer and blogger"
"jane_smith"
""

Пример

Использование defer с другими методами QuerySet. Отложим загрузку поля и применим фильтрацию:

pythonfrom myapp.models import Article
from datetime import date

# Defer 'content' and filter by date
articles = (Article.objects
      .defer('content')
      .filter(created_at__date__gte=date(2025, 1, 1)))
for article in articles:
  print(article.title)

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

python"New Year Article"
"January Update"

Пример

Отложим загрузку поля для связанной модели с помощью select_related:

pythonfrom myapp.models import Article

# Defer 'content' field and load related author
articles = (Article.objects
      .select_related('author')
      .defer('content'))
for article in articles:
  print(f"Article: {article.title}, Author: {article.author.name}")

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

python"Article: First Article, Author: John Doe"
"Article: Second Article, Author: Jane Smith"

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

  • метод only,
    который загружает только указанные поля
  • метод select_related,
    который подгружает связанные объекты одним запросом
  • метод prefetch_related,
    который подгружает связанные объекты отдельными запросами
  • метод values,
    который возвращает QuerySet словарей вместо объектов