Как я могу проверить, что Django @cached_property является кэшированным?

В приведенном ниже примере у меня есть вопросы.

Пример

from django.utils.functional import cached_property

class Product(models.Model):
    class ProductType(models.TextChoices):
        PRODUCT = 'PRODUCT', _('Product')
        LISTING = 'LISTING', _('Listing')

    my_model = models.ForeignKey(MyModel, on_delete=models.CASCADE, related_name='products')
    product_type = models.CharField(max_length=7, choices=ProductType.choices)

class MyModel(models.Model):
    ...
    
    @cached_property
    def listing(self):
        return self.products.get(product_type=Product.ProductType.LISTING)

Вопросы

  1. Кэшируется ли свойство listing на объекте MyModel? Я спрашиваю, потому что это доступ к .get() кверисету, что имеет более серьезные последствия.

Ex:

instance = MyModel()
instance.listing # hits db
instance.listing # gets from cache?
  1. Как я могу создать сценарий, чтобы проверить и убедиться, что кэширование instance.listing действительно происходит? Я читал, что нужно искать в методе __dict__ в instance.listing.__dict__, но не заметил ничего конкретного.

Если вы прочитаете источник этого декоратора https://docs.djangoproject.com/en/4.0/_modules/django/utils/functional/#cached_property, то увидите, что вы, вероятно, проверяете это не в том месте. listing будет кэшироваться на самом экземпляре, что означает, что вам нужно проверить instance.__dict__.

Я наградил @Sardorbek Imomaliev ответом за то, что он указал мне правильное направление. Для ясности для всех, кто наткнется на этот вопрос, вот мои выводы

  1. Кэшируется ли свойство listing на объекте MyModel? Я спрашиваю, потому что он обращается к .get() набора запросов, что имеет более серьезные последствия.
  2. .

Ответ: да

  1. Как я могу создать сценарий для проверки и подтверждения того, что кэширование instance.listing действительно происходит?

Ответ:

>>> inst = MyModel.objects.first()
>>> inst.__dict__.keys()
dict_keys(['_state', 'id', 'user_id', 'title', 'slug'])
>>> inst.listing
<Listing: Some Listing Instance>
>>> inst.__dict__.keys()
dict_keys(['_state', 'id', 'user_id', 'title', 'slug', 'listing'])
  1. Бонус: Как выглядит, если это не @cached_property, а обычный @property?

Ответ: 'listing' не добавляется к inst.__dict__.

>>> inst = MyModel.objects.first()
>>> inst.__dict__.keys()
dict_keys(['_state', 'id', 'user_id', 'title', 'slug'])
>>> inst.listing
<Listing: Some Listing Instance>
>>> inst.__dict__.keys()
dict_keys(['_state', 'id', 'user_id', 'title', 'slug'])

для удаления кэшированного свойства, вы можете использовать del inst.listing.Таким образом, вы можете использовать сигналы для удаления кэша свойств всякий раз, когда модель продукта изменяется

Вернуться на верх