Использование кэша Django для хранения свойств модели

У меня есть модель изображения с внешним ключом к родительской модели.

class MyImage(models.Model):
    parent = models.ForeignKey(ParentModel, related_name='images', on_delete=models.CASCADE)
    image = models.ImageField(upload_to='images')

Я также использую django-s3-storage, чтобы эти изображения обслуживались из частного ведра S3.

Когда я запрашиваю url изображения в шаблоне, используя (это детальное представление на основе класса, я также получаю изображения в представлении списка на основе класса):

{% for image in object.images.all %}
    <img src="{{image.image.url}}" alt="">
{% endfor %}

значение, возвращаемое из url - это подписанный url, и это нормально. Я бы предпочел не делать свой bucket публичным. Проблема в том, что этот подписанный url генерируется каждый раз, когда я получаю url из модели изображения, что предотвращает кэширование изображения в браузере, поскольку подпись меняется при каждом запросе. Это не идеально, поскольку эти изображения будут редко меняться, и я бы хотел, чтобы они кэшировались в браузере для снижения затрат на S3.

В настоящее время я также использую встроенное кэширование Django (в моем случае я пока использую кэширование базы данных). Встроенное кэширование позволяет мне кэшировать фрагменты шаблонов следующим образом:

{% for image in object.images.all %}
    {% cache 1440 object_image object %}
        <img src="{{image.image.url}}" alt="">
    {% endcache %}
{% endfor %}

Это вроде бы работает нормально, поскольку фрагмент кэшируется с подписанным url; однако я использую изображения в нескольких разных шаблонах, и у меня также есть дополнительная логика, которую я использую для получения изображений на основе других полей модели изображений (default, thumbnail и т.д.). Это означает, что одно изображение будет хранить несколько различных кэшированных значений, каждое из которых будет иметь свой подписанный url. Это не конец света, но я бы хотел, чтобы подписанный url изображения был одинаковым для всех шаблонов.

Читая документацию по кэшированию, не существует встроенного декоратора, который можно было бы использовать для свойства модели и который функционировал бы так же, как тег фрагмента шаблона.

Я хотел бы добавить свойство модели к моей модели изображения, которое оформлено так, чтобы url изображения кэшировалось, чтобы я мог просто вызвать его из любого шаблона, и оно вернет тот же подписанный url из кэша, например:

class MyImage(models.Model):
    parent = models.ForeignKey(ParentModel, related_name='images', on_delete=models.CASCADE)
    image = models.ImageField(upload_to='images')

    @property
    @cache('object_image', object)
    def url(self):
        return self.image.url

Поскольку не похоже, что существует декоратор, это тот случай, когда я должен просто реализовать свой собственный декоратор и/или получить доступ к API кэша непосредственно внутри моего свойства url? Или мне не хватает существующего интерфейса, с помощью которого я могу получить доступ к встроенным функциям и использовать их вместо этого?

from django.core.cache import cache

class MyImage(models.Model):
    parent = models.ForeignKey(ParentModel, related_name='images', on_delete=models.CASCADE)
    image = models.ImageField(upload_to='images')

    @property
    def url(self):
        return cache.get_or_set(self, self.image.url, 1440)
Вернуться на верх