Django 在仍然可以访问外来对象的情况下注释总和
假设我有一个简单的购物车系统,它有以下几种型号:Django 在仍然可以访问外来对象的情况下注释总和,django,Django,假设我有一个简单的购物车系统,它有以下几种型号: 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:
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,
)
当用户下订单时,会为他们订购的每个产品创建一个OrderItem
对象,这让我知道(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)
但是使用这种方法,我不能使用
订购\u item.product.featured\u image
。有什么办法我可以同时拥有这两样东西吗?也就是说,数量全部相加,并按从多到少的顺序排列,并且能够使用order\u item.product.featured\u image
我认为在使用values()
后,没有办法获得对象属性,因为queryset返回的dicts带有选择键值,而不是模型对象。您可以执行其他查询,以获取具有特色图像的产品,并将其映射到您的订单\u项目
:
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)
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\u items\u by\u quantity
。此外,您应该对图像执行预回迁相关()