2017-02-10 49 views
0

比方說,我有這些模型一個簡單的購物車系統,因爲他們訂購的每個產品創建一個OrderItem對象詮釋總和,同時仍然能夠訪問異物

from django.db import models 
from django.utils import timezone 


class Product(models.Model): 
    name = models.CharField(max_length=255) 
    # More fields... 

    @property 
    def featured_image(self): 
     try: 
      return self.productimage_set.all()[0] 
     except IndexError: 
      return None 

    def __str__(self): 
     return self.name 


class ProductImage(models.Model): 
    product = models.ForeignKey(Product, on_delete=models.CASCADE) 
    image = models.FileField(upload_to='products/') 
    # More fields... 

    def __str__(self): 
     return self.product.name 


class Order(models.Model): 
    created = models.DateTimeField(default=timezone.now) 
    # More fields... 

    def __str__(self): 
     return str(self.pk) 


class OrderItem(models.Model): 
    order = models.ForeignKey(Order, on_delete=models.CASCADE) 
    product = models.ForeignKey(Product, on_delete=models.CASCADE) 
    quantity = models.PositiveIntegerField() 
    # More fields... 

    def __str__(self): 
     return 'Order %s: %s of %s' % (
      self.order_id, 
      self.quantity, 
      self.product.name, 
     ) 

當用戶下訂單, ,它讓我知道(1)他們購買了哪種產品,以及(2)他們購買了多少產品。

現在,假設我想向用戶展示他們訂購了哪些產品。我將使用該數據作爲一個例子:

Order 1: 
Product A: 10 

Order 2: 
Product A: 10 
Product B: 5 

Order 3: 
Product A: 10 
Product B: 5 
Product C: 5 

此特定用戶應顯示的產品的順序:

Product A: 30 total 
Product B: 10 total 
Product C: 5 total 

這是實現這的代碼:

order_items_by_quantity = OrderItem.objects.values(
    'product__name', 
).annotate(
    total_purchased=Sum('quantity'), 
).order_by(
    '-total_purchased', 
) 

for order_item in order_items_by_quantity: 
    print(order_item) 

但是用這種方法,我不能使用order_item.product.featured_image。有沒有辦法讓我擁有這兩件事?也就是說,所有的數量總計和從大多數訂購到至少使用order_item.product.featured_image的能力。

回答

0
order_items_by_quantity = OrderItem.objects.values(
    'product__name', 'product_id' 
).annotate(
    total_purchased=Sum('quantity'), 
).order_by(
    '-total_purchased', 
) 

for order_item in order_items_by_quantity: 
    pid = order_item['product_id'] 
    image = ProductImage.objects.filter(product_id=pid).first() 
    print(order_item, image) 
0

我不認爲有一種方式,你使用values()後的查詢集返回與SELECT鍵值類型的字典,而不是模型對象獲取對象的屬性。你可以做更多的查詢來獲取產品的特色照片並將其映射到您的order_items

order_items_by_quantity = OrderItem.objects.values(
    'product__name', 'product_pk' 
).annotate(total_purchased=Sum('quantity')).order_by('-total_purchased') 

product_image_map = {} 
for product in Product.objects.prefetch_related('productimage_set'): 
    product_image_map[product.pk] = product.featured_image 

for order_item in order_items_by_quantity: 
    order_item['featured_image'] = product_image_map[order_item['product_id']] 

這樣,您爲您的產品每次迭代order_items_by_quantity時間問一次數據庫,沒有。另外,你應該對你的圖像做prefetch_related()