Какие методы в Django ORM используются для выборки только определенных полей модели

Ответ

Для оптимизации запросов и выборки только необходимых полей в Django ORM используются методы only(), defer() и values().

1. only(*fields)

Загружает только указанные поля. Остальные поля модели будут загружены "лениво" (lazy) при первом обращении к ним, что вызовет дополнительный запрос к БД.

Когда использовать: Когда вы точно знаете, что вам понадобятся только несколько полей объекта модели.

# Будет выполнен один SQL-запрос: SELECT id, name FROM myapp_mymodel;
users = MyModel.objects.only('id', 'name')

for user in users:
    print(user.name)  # Данные уже загружены
    print(user.bio)   # Вызовет новый запрос к БД для этого объекта

2. defer(*fields)

Противоположность only(). Загружает все поля модели, кроме указанных. Отложенные поля также подгружаются при обращении к ним.

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

# Выберет все поля, кроме 'bio' и 'profile_picture'
users = MyModel.objects.defer('bio', 'profile_picture')

3. values(*fields)

Возвращает QuerySet, который при итерации выдает словари (dict), а не экземпляры модели. Это самый эффективный способ, если вам нужны только данные без методов модели.

Когда использовать: Для сериализации данных, передачи в JSON или когда объекты модели не требуются.

# Вернет список словарей: [{'id': 1, 'name': 'John'}, ...]
data = MyModel.objects.values('id', 'name')

Ключевое отличие: only() и defer() возвращают полноценные объекты модели, позволяя вызывать их методы, в то время как values() возвращает словари, что значительно быстрее и требует меньше памяти.

Ответ 18+ 🔞

Ну что, дружок, смотри сюда, я тебе сейчас на пальцах объясню, как в этом вашем Django ORM не нагружать базу лишними запросами, а то ведь можно так наебнуться с производительностью, что потом волосы на жопе дыбом встанут.

Вот представь, у тебя модель MyModel, и в ней полей — овердохуища. А тебе из неё нужно всего два поля: id да name. Ну и зачем тебе тащить из базы всю эту простыню, включая какую-нибудь здоровенную биографию bio? Правильно, нихуя не нужно.

1. only(*fields) — «Только эти, ёпта!»

Скажешь ему: «Эй, Django, дай мне только id и name, а остальное — похуй». Он тебе и выдаст.

# Сделает один запрос: SELECT id, name FROM myapp_mymodel;
users = MyModel.objects.only('id', 'name')

for user in users:
    print(user.name)  # Всё ок, данные уже тут
    print(user.bio)   # А вот тут, сука, он пойдёт в базу за этой биографией для КАЖДОГО объекта отдельно!

Вот в чём подвох, блядь! Если потом полезешь в поле, которое не запросил — получишь дополнительный запрос в лоб. Так что думай головой, что тебе реально нужно.

2. defer(*fields) — «Всё, кроме этого говна»

Обратная ситуация. Говоришь: «Загрузи всё, но вот эти поля — bio и profile_picture — пока не трогай, они мне как кот сука собака».

# Загрузит все поля, кроме этих двух говёных
users = MyModel.objects.defer('bio', 'profile_picture')

По сути, то же самое, что и only(), только сформулировал от противного. Удобно, когда полей, которые не нужны, меньше, чем тех, что нужны.

3. values(*fields) — «Дайте мне голые данные, без ваших моделей!»

А вот это, дружок, самый жёсткий и быстрый способ, если тебе не нужны твои навороченные объекты модели со всеми их методами. Ты получаешь просто словари. Никаких лишних накладных расходов, чистая выжимка.

Когда использовать: Когда пишешь API, гонишь JSON или просто пачку данных для отчёта. Скорость и память — просто пиздец какие хорошие.

# Вернёт список словарей: [{'id': 1, 'name': 'John'}, ...]
data = MyModel.objects.values('id', 'name')

И главное отличие, запомни, как «Отче наш»:

  • only() и defer() — возвращают объекты модели. Ты можешь с ними работать как обычно, вызывать методы, но рискуешь нарваться на дополнительные запросы.
  • values() — возвращает словари (dict). Объектов модели нет, методов нет — зато нихуя не тормозит и памяти жрёт как мартышлюшка.

Выбирай с умом, а то потом будешь сидеть и думать: «И кто же этот пидарас шерстяной написал такой медленный код?» А это будешь ты сам, чувак. Сам от себя охуеешь.