2014-02-08 68 views
1

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

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") 

回答

3

这里是一种方法,你可以得到产品w /最低价格。

做出的产品模型“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属性才能正常工作,你需要添加“价格”相关的名称在价格型产品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 
+0

谢谢......但我真的很想在产品模型上不添加额外字段的方式,但如果这是唯一的方法,那么我必须这样做。 – pkdkk

+0

此解决方案没有创建额外的字段。 @property方法不会创建数据库字段。或者我误解了你? – user772401

+0

如果你指的是@属性/'current_price',这只是一个python函数来帮助你处理你的模型,数据库不会被触及。 – user772401

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 
+0

@pkdkk刚刚编​​辑,因为我的第一个答案有一个错误。让我知道这是否适合你。 – sgarza62