cached_property
Декоратор cached_property применяется к методам классов и позволяет кешировать результат их выполнения. При первом обращении к свойству метод вызывается и вычисляет значение, которое сохраняется в атрибуте экземпляра. При последующих обращениях возвращается закешированное значение, что значительно повышает производительность, особенно при работе с тяжелыми вычислениями или запросами к базе данных.
Синтаксис
from django.utils.functional import cached_property
class MyClass:
@cached_property
def my_property(self):
# Вычисляем значение
return result
Декоратор принимает следующие параметры:
-
name- имя свойства (опционально, по умолчанию используется имя метода)
Пример
Создадим класс Article с закешированным свойством для получения статистики:
from django.db import models
from django.utils.functional import cached_property
class Article(models.Model):
title = models.CharField(max_length=100)
views = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
comments = models.IntegerField(default=0)
@cached_property
def total_engagement(self):
# Тяжелое вычисление, которое выполняется один раз
print("Computing total engagement...")
return self.views + self.likes + self.comments
Демонстрация работы кеширования:
from myapp.models import Article
article = Article.objects.get(id=1)
print(article.total_engagement)
print(article.total_engagement)
print(article.total_engagement)
Результат выполнения кода:
"Computing total engagement..."
"150"
"150"
"150"
Как видно из примера, сообщение о вычислении выводится только один раз, а последующие обращения возвращают закешированное значение.
Пример
Использование cached_property с запросами к базе данных для оптимизации производительности:
from django.db import models
from django.utils.functional import cached_property
class User(models.Model):
name = models.CharField(max_length=50)
email = models.CharField(max_length=100)
@cached_property
def recent_articles(self):
# Выполняется один раз при первом обращении
return self.article_set.filter(status='published')[:5]
@cached_property
def total_comments(self):
from .models import Comment
return Comment.objects.filter(user=self).count()
Пример использования свойств в коде:
from myapp.models import User
user = User.objects.get(id=1)
# Первое обращение - выполняются запросы к БД
articles = user.recent_articles
comments = user.total_comments
# Повторные обращения - значения берутся из кеша
print(len(user.recent_articles))
print(user.total_comments)
Результат выполнения кода:
"5"
"23"
Пример
Переопределение кешированного свойства для обновления значения:
from django.db import models
from django.utils.functional import cached_property
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.IntegerField()
quantity = models.IntegerField()
@cached_property
def total_value(self):
return self.price * self.quantity
def update_cache(self):
# Удаляем закешированное значение для пересчета
del self.total_value
Демонстрация обновления кеша:
from myapp.models import Product
product = Product.objects.get(id=1)
print(product.total_value)
# Изменяем данные продукта
product.price = 200
# Обновляем кеш
product.update_cache()
# Вычисляем заново
print(product.total_value)
Результат выполнения кода:
"500"
"1000"
Смотрите также
-
декоратор
classproperty,
который создает свойства уровня класса -
декоратор
method_decorator,
который применяет декораторы к методам классов -
функция
lazy,
которая откладывает выполнение кода до момента обращения -
функция
mark_safe,
которая указывает Django не экранировать строку