Django defer, only

За замовчуванням ORM в Django завантажує з бази даних при запиті, усі поля об’єкта. У разі, коли перетворення записи бази даних в об’єкт Python займає тривалий час, або полів дуже багато, або будь-яке з полів містить велику кількість даних – це не продуктивно.

Тепер ми можемо сказати ORM-у вибирати тільки певні поля з таблиці, з розрахунком на те, що інші не будуть використані.
Наведу приклад, припустимо у нас є модель Book

from django.db import models
from django.contrib.auth.models import User

class Book (models.Model):
    """
    Simple model

    """
    author = models.ForeignKey (User)
    title = models.CharField (max_length = 255, db_index = True)
    content = models.TextField ()

    def __unicode__ (self):
        return self.title

У полі title – зберігається назва книги, а в content – текст книги цілком. Якщо нам необхідно вивести весь список книг, ми зробимо запит:

books = Book.objects.all()

На що Джанго відповість таким запитом до БД:

SELECT "testapp_book". "Id", "testapp_book". "Author_id", 
"testapp_book". "Title", "testapp_book". "Content" FROM "testapp_book"
 LIMIT 21

Як бачимо, content – у списку обираних полів. Для нас це критично продуктивністю. А тепер зробимо по іншому і використовуємо defer:

books = Book.objects.all().defer( 'content')

І побачимо наступний запит:

SELECT "testapp_book". "Id", "testapp_book". "Author_id", 
"testapp_book". "Title" FROM "testapp_book" LIMIT 21

Ну от, життя налагоджується. Якщо тепер ми звернемося до поля content екземпляра моделі Book:

print books[0].content

Те Джанго запитає у БД наступне:

SELECT "testapp_book". "Content" FROM "testapp_book" 
WHERE "testapp_book". "Id" = 1

Як бачимо, defer – це відкладене завантаження полів. Щоб вимкнути її для об’єкта QuerySet достатньо викликати метод defer з аргументом None. Щоб відкласти завантаження декількох полів, достатньо перерахувати їх як аргументи для defer:

Book.objects.defer('author_id', 'content')

Тепер про only. Only – це метод QuerySet, який працює схожим чином з defer, тільки навпаки. За допомогою only ми можемо перерахувати поля які нам необхідно отримати, а всі інші обрані з бази не будуть. Наприклад якщо нам необхідний тільки title книги і логін її творця, то запит до ORM буде наступним:

books = Book.objects.select_related().only(
'title', 'author__username')

http://docs.djangoproject.com/en/dev/ref/models/querysets/#defer-fields




coded by nessus