在下面的例子中,我有一些问题。
示例
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()
,这有更大的影响。
例如:
instance = MyModel()
instance.listing # hits db
instance.listing # gets from cache?
1.我如何设置一个场景来检查和验证instance.listing
的缓存是否确实发生了?我阅读了instance.listing.__dict__
的__dict__
方法,但没有注意到任何具体的内容。
3条答案
按热度按时间mnemlml81#
如果您阅读了这个装饰器的源代码https://docs.djangoproject.com/en/4.0/_modules/django/utils/functional/#cached_property,您会发现您可能在错误的位置检查了它。
listing
将缓存在示例本身上,这意味着您需要检查instance.__dict__
。8yoxcaq72#
我给@Sardorbek Imomaliev颁发了一个答案,因为它为我指明了正确的方向。为了让任何偶然发现这个问题的人清楚起见,以下是我的发现。
1.列表属性是否缓存在MyModel对象上?我这样问是因为它正在访问一个queryset的.get(),这有更大的含义。
答:是的。但是,如果缓存对象的属性发生变化,这些变化在缓存对象中是不可见的。例如:如果价格从$4变为$5,则缓存的属性仍将显示$4。
1.如何设置一个场景来检查和验证
instance.listing
的缓存是否确实发生了?答:
1.额外好处:如果它不是
@cached_property
,而只是一个普通的@property
,它看起来会是什么样子?答案:
'listing'
不会添加到inst.__dict__
。8aqjt8rx3#
要删除缓存的属性,您可以使用
del inst.listing
。因此,只要产品型号发生更改,您基本上就可以使用信号删除此属性缓存