2014-02-08 2 views
1

나는 Django 모델들, Product 클래스와 Price 클래스를 가지고있다. 제품은 여러 가격을 가질 수 있지만 "최신"가격 만 현재 가격! 가장 낮은 가격과 가장 높은 가격이 필요한 제품 쿼리가 있지만 현재 가격 만 있습니다. 제품에 2 개 이상의 가격이있는 경우 원하는 최신 가격 만 제공됩니다.Django Queryset 최저/최고 가격을 받으십시오! one to many

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

최소 가격으로 제품을 구입할 수있는 방법 중 하나입니다. CURRENT_PRICE 속성이 제대로 작동하려면, 당신은 당신의 가격 모델 제품 FK 필드에 '가격'과 관련된 이름을 추가 할 필요가

제품 모델에 '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 

,

이제
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 

Y ou가 모델 관리자를 대신하여이 작업을 수행 할 수 있습니다. 자세한 내용은 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

@ property/'current_price'를 말하는 경우, 이것은 모델 작업에 도움이되는 파이썬 함수 일 뿐이며 데이터베이스는 건드리지 않습니다 .. – 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