说我有一个类似
的模型class Product(models.Model):
name = models.CharField(max_length=64)
[...]
和另一个像
class Price(models.Model):
product = models.ForeignKey('Product')
date = models.DateField()
value = models.FloatField()
[...]
我希望在modelAdmin中显示产品,最后一个价格在列中注册。
到目前为止,我找到的唯一方法是将以下方法添加到产品对象中:
@property
def last_price(self):
price = Price.objects.filter(product=self.pk).order_by("-date")
return price[0].value if price else None
然后将last_price添加到Product的ModelAdmin中的list_display。我不喜欢这种方法,因为它最终会对显示的每一行进行查询。
在代码中有更好的方法吗?或者我是否必须在Product表中创建一个列并在那里缓存最后一个价格?。
谢谢!
答案 0 :(得分:2)
减少每个条目的查询使用以下内容:
Price.objects.filter(product=self.pk).order_by("-date").select_related('product')
这将减少每个对象的产品查询,希望它有用,请投票
答案 1 :(得分:1)
您所拥有的更清晰版本:
def last_price(self):
latest_price = self.price_set.latest('date')
return latest_price.value if latest_price else None
但这仍然涉及对每个项目的查询。
如果您想避免这种情况,我建议您向latest_price
添加Product
列。然后,您可以为post_save
设置Price
信号,然后更新相关的Product
latest_price
(这可能是ForiegnKey或值本身。)
<强>更新强>
这是一个接收器,可在您保存Price
时更新产品的最新价格值。显然,这假设您按时间顺序保存Price
模型,因此保存的最新模型是latest_value
@receiver(post_save, sender=Price)
def update_product_latest_value(sender, instance, created, **kwargs):
if created:
instance.product.latest_value = instance.value
instance.product.save()