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
Читайте також:
- Django admin filter by ranges of ages
- Retrieving elements in a specific order in django
- Django mongoengine cache backend
- django postgresql та SCHEMA для таблиць
- django-stdimage traceback "The '%s' attribute has no file associated with it"
- Python + CouchDB
- Django suit admin inline pagination
- Fix Django 1.4 admin_site ForeignKeyRawIdWidget issue
- Ordering related objects in Django
- django custom admin