Django Queryset获得最低/最高价格!一对多

时间:2014-02-08 16:16:44

标签: django django-models django-queryset

我有一些Django模型,一个Product类和一个Price类。一个产品可以有多个价格,但只有当前价格的“最新”价格!我有一个产品查询,我需要最低的价格和最高的价格,但只有当前的价格。如果一个产品有2个或更多的价格,它只是我想要的最新价格!

class Product(models.Model):
    productname = models.CharField(max_length=1024)

class Price(models.Model):
    product = models.ForeignKey(Product)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created = models.DateTimeField(auto_now_add=True)

查询集中的一个示例,我想要最低和最高,但只有当前价格。 “price__price__gt”也是如此。这也应该只是我希望它与之合作的当前价格。

Product.objects.filter(price__price__gt=1000).order_by("price")

2 个答案:

答案 0 :(得分:3)

以下是您可以通过最低价格获得产品的一种方式。

在产品型号上创建'current_price'属性,

class Product(models.Model):
    productname = models.CharField(max_length=1024)

    @property
    def current_price(self):
        """Returns last price if any prices exist, else None
        """
        if self.price.all():
            return self.price.order_by('-created')[0].price

要使current_price属性正常工作,您需要在Price model product fk字段中添加“价格”相关名称,

class Price(models.Model):
    product = models.ForeignKey(
        Product, related_name='price')
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created = models.DateTimeField(auto_now_add=True)

现在您可以按以下方式过滤最低价格,

qs = [p for p in Product.objects.all() if p.current_price]
# Returns a list of products that have a current price

# To get the lowest price,
cheapest_product = min(qs, key=lambda x: x.current_price)
cheapest_product.current_price

# To get the highest price,
most_expensive_product = max(qs, key=lambda x: x.current_price)
most_expensive_product.current_price

您可以让模特经理为您执行此操作,有关详细信息,请参阅django docs

最好你想要一个可以这样工作的经理,

Product.objects.cheapest()  # returns the single cheapest 'current' price.
Product.objects.most_expensive()  #returns most expensive (highest) price

答案 1 :(得分:2)

这应该可以解决问题。

from django.db.models import Max

prods_with_prices = []
for prod in Product.objects.all():
    prices = Prices.objects.filter(product = prod).annotate(current_price=Max('created'))
    prods_with_prices.append({'product': prod, 'price': prices.current_price})
costly_prod = max(prods_with_prices, key = lambda x: x['price'])['product']
cheap_prod = min(prods_with_prices, key = lambda x: x.['price'])['product']

print "Most expensive product: " + costly_prod
print "Least expensive product: " + cheap_prod