← Назад к вопросам

Как ограничить количество полей в queryset?

2.2 Middle🔥 201 комментариев
#Django#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ограничение полей в queryset Django ORM

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

1. Метод values() и values_list()

Самый простой способ — использовать values() для получения словарей с выбранными полями:

from django.db import models

# Вместо:
users = User.objects.all()  # загрузит все поля

# Используй:
users = User.objects.values("id", "name", "email")
# Результат: [{'id': 1, 'name': 'John', 'email': 'john@example.com'}, ...]

values_list() возвращает кортежи вместо словарей:

users = User.objects.values_list("name", "email")
# Результат: [('John', 'john@example.com'), ...]

# С flat=True для одного поля:
names = User.objects.values_list("name", flat=True)
# Результат: ['John', 'Jane', ...]

2. Метод only()

Загружает только указанные поля, оставляя объекты модели (не словари):

users = User.objects.only("id", "name", "email")
# Результат: объекты User с загруженными только этими полями

for user in users:
    print(user.name)  # OK, поле загружено
    print(user.bio)   # Extra query! Поле не загружено

3. Метод defer()

Противоположность only() — исключает указанные поля из загрузки:

users = User.objects.defer("bio", "large_text_field")
# Загружаются все поля, кроме bio и large_text_field

Это полезно для больших текстовых полей, которые редко нужны.

4. Применение к связанным объектам

Можно ограничить поля связанных моделей (ForeignKey, OneToOne):

from django.db.models import Prefetch

# Загружаем посты только с id и title, пользователей с id и name
posts = Post.objects.select_related("author").only("id", "title", "author__id", "author__name")

# С prefetch_related:
users = User.objects.prefetch_related(
    Prefetch(
        "posts",
        queryset=Post.objects.only("id", "title")
    )
)

5. Практический пример

# API endpoint, где нужен только список имён и email
users = User.objects.values_list("id", "name", "email", named=True)
# Результат: namedtuple с доступом по атрибутам
for user in users:
    print(f"{user.name} ({user.email})")

# Для объектов модели:
users = User.objects.only("id", "name", "email")
for user in users:
    user_dict = {
        "id": user.id,
        "name": user.name,
        "email": user.email
    }

Когда что использовать?

  • values() / values_list() — когда нужны простые данные (списки, экспорт)
  • only() — когда работаешь с объектами модели, но нужны не все поля
  • defer() — когда нужны все поля, кроме одного-двух больших

Ограничение полей — это один из ключевых приёмов оптимизации N+1 проблем в Django и снижения нагрузки на БД.

Как ограничить количество полей в queryset? | PrepBro