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
。此外,您应该对图像执行
预回迁相关()