假设我的项目中有一个Product
模型:
class Product(models.Model):
price = models.IntegerField()
我想要一些统计信息(假设我想跟踪价格随时间的变化)
class ProductStatistics(models.Model):
created = models.DateTimeField(auto_add_now=True)
statistics_value = models.IntegerField()
product = models.ForeignKey(Product)
@classmethod
def create_for_product(cls, product_ids):
statistics = []
products = Product.objects.filter(id__in=products_ids)
for product in products:
statistics.append(
product=product
statistics_value=product.price
)
cls.objects.bulk_create(statistics)
@classmethod
def get_latest_by_products_ids(cls, product_ids):
return None
我在实现get_latest_by_products_ids
方法时遇到问题。我只需要最新的统计信息,因此无法执行以下操作:
@classmethod
def get_latest_by_products_ids(cls, product_ids):
return cls.objects.filter(product__id__in=product_ids)
因为这将返回我过去收集的所有统计信息。如何将查询限制为每个产品的最新查询?
编辑 我正在使用PostgreSQL数据库。
答案 0 :(得分:2)
Querysets already have a last()
method(以及first()
方法也是FWIW)。唯一的问题是要定义为“最后一个”的内容,因为这取决于查询集的顺序...但是假设您要按创建日期最后一个(created
字段),也可以use the lastest()
method:
@classmethod
def get_latest_by_products_ids(cls, product_ids):
found = []
for pid in products_ids:
found.append(cls.objects.filter(product_id=pid).latest("created"))
return found
请注意:Django's coding style is to use the Manager
(and eventually the Queryset
) for operations working on the whole table,因此应该在您的模型上创建自定义管理器,而不是在模型上创建类方法:
class productStatisticManager(models.Manager):
def create_for_products(self, product_ids):
statistics = []
products = Product.objects.filter(id__in=products_ids)
for product in products:
statistics.append(
product=product
statistics_value=product.price
)
self.bulk_create(statistics)
def get_latest_by_products_ids(cls, product_ids):
found = []
for pid in products_ids:
last = self.objects.filter(product_id=pid).latest("created")
found.append(last)
return found
class ProductStatistics(models.Model):
created = models.DateTimeField(auto_add_now=True)
statistics_value = models.IntegerField()
product = models.ForeignKey(Product)
objects = ProductStatisticManager()
答案 1 :(得分:0)
将方法放入产品模型中,将更加容易:
class Product(models.Model):
price = models.IntegerField()
def get_latest_stat(self):
return self.productstatistics_set.all().order_by('-created')[0] # or [:1]
使用[:1]而不是[0]将返回单个元素的QuerySet,而[0]将仅返回模型类的一个Object。
例如
>>> type(cls.objects.filter(product__id__in=product_ids).order_by('-created')[:1])
<class 'django.db.models.query.QuerySet'>
>>> type(cls.objects.filter(product__id__in=product_ids).order_by('-created')[0])
<class 'myApp.models.MyModel'>