Как я могу проверить, что 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)
Вопросы
- Кэшируется ли свойство
listing
на объектеMyModel
? Я спрашиваю, потому что это доступ к.get()
кверисету, что имеет более серьезные последствия.
Ex:
instance = MyModel()
instance.listing # hits db
instance.listing # gets from cache?
- Как я могу создать сценарий, чтобы проверить и убедиться, что кэширование
instance.listing
действительно происходит? Я читал, что нужно искать в методе__dict__
вinstance.listing.__dict__
, но не заметил ничего конкретного.
Если вы прочитаете источник этого декоратора https://docs.djangoproject.com/en/4.0/_modules/django/utils/functional/#cached_property, то увидите, что вы, вероятно, проверяете это не в том месте. listing
будет кэшироваться на самом экземпляре, что означает, что вам нужно проверить instance.__dict__
.
Я наградил @Sardorbek Imomaliev ответом за то, что он указал мне правильное направление. Для ясности для всех, кто наткнется на этот вопрос, вот мои выводы
- Кэшируется ли свойство listing на объекте MyModel? Я спрашиваю, потому что он обращается к .get() набора запросов, что имеет более серьезные последствия. .
Ответ: да
- Как я могу создать сценарий для проверки и подтверждения того, что кэширование
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'])
- Бонус: Как выглядит, если это не
@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
.Таким образом, вы можете использовать сигналы для удаления кэша свойств всякий раз, когда модель продукта изменяется