Представляю релиз стабильной батарейки django_model_cached_property для кэширования property для отдельных объектов моделей в Django.
Я уже рассказывал, что evileg_core содержит подобный функционал, но вот решил вывести это кэширование в отдельный пакет. Это связано с тем, что я не успеваю поддерживать такой большой пакет, а отдельнуй небольшой функционал использую и в других своих проектах. Поэтому мне показалось логичным разбить крупный проект на самостоятельные проекты, чтобы было проще заниматься поддержкой по крайней мере наиболее востребованного функционала, хотя бы в рамках своих проектов. Также надеюсь, что этот пакет окажется очень полезным и для других разработчиков.
Назначение
Пакет используется для кэширования результата методов объектов моделей на период, который дольше существования инстанса обхекта во время обработки запроса пользователя. Это необходимо для того, чтобы кэшировать тяжёлые запросы к базе данных, результаты которых теоретически не должны изменяться довольно часто, но при этом их вызов каждый раз при запросе пользователя может сильно уменьшить скорость работы пользователя с Django приложением. Это может быть полезно, например, для информации о том, лайкнул ли пользователь какой-то объект, а также количество лайкнувших, в том случае если используются Generic связи в базе данных. К сожалению такие связи работают не так быстро, как хотелось бы. Поэтому правильное кэширование может очень сильно ускорить работу сайта.
А теперь расскажу, как пользоваться данным функционалом
Установка
pip install -U django-model-cached-property
Установка и настройка требований
Установите Redis для кэширования.
sudo apt install redis-server
Настройте setup.py вашего проекта django.
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } }
Использование
Пакет содержит две функции:
model_cached_property - это декоратор для методов класса, который будет кэшировать результаты вызова свойства для отдельных записей.
invalidate_model_cached_property - это функция для инвалидации метода на свойстве записи модели.
model_cached_property
Вы можете использовать этот декоратор следующим образом.
from django_model_cached_property import model_cached_property class Article(models.Model): @model_cached_property def comments_count(self): return self.comments.count()
Это означает, что вы кешируете количество комментариев для каждой записи статьи в вашем проекте Django.
Вы можете установить время ожидания кеша 3000 секунд следующим образом.
class Article(models.Model): @model_cached_property(timeout=3000) def comments_count(self): return self.comments.count()
По умолчанию тайм-аут кэширования составляет 60 секунд, вы можете настроить его глобально в settings.py .
MODEL_CACHED_PROPERTY_TIMEOUT = 300000
Кроме того, вы можете использовать кэширование свойства модели с входными аргументами.
И в этом случае кэширование будет оцениваться для всех входных наборов аргументов.
Например, кэширование с авторизованным пользователем.
class Article(models.Model): @model_cached_property def __user_in_bookmarks(self, user): return self.bookmarks.filter(user=user).exists() def user_in_bookmarks(self, user): return self.__user_in_bookmarks(user) if user.is_authenticated else False
invalidate_model_cached_property
Эта функция делает недействительными все ключи кеша в свойстве для одной записи модели в базе данных.
Например
article = get_object_or_404(Article, pk=12) invalidate_model_cached_property(article, article.comments_count)
В этом случае вы сделаете недействительными все кэшированные ключи для статьи с первичным ключом 2.
ВНИМАНИЕ - Ограничение
Ограничение этой функциональности кэширования состоит в том, что вы можете использовать ее только с уникальными входными аргументами. Это означает, что с объектом AnonymousUser это работать не будет, так как в каждом запросе информация об объекте AnonymousUser будет разной, хотя он и будет вызываться одним и тем же пользователем. Поэтому используйте его только для уникальной информации.
Заключение
Дорогие пользователи сайта EVILEG, если Вам не будет трудно, то пожалуйста, оцените звездочкой репозиторий проекта на GitHub
О хорошая статья. Для какой ветки Django будет работать эта батарейка?
Я тестировал только на Django 4, но сам код не менялся пожалуй с версии Django 2, так что предполагаю, что должно работать во всех версиях, но если протестируете на более ранних версиях, и будет нормально работать, то дайте фидбек. Спасибо.