Python Django:如何按相关对象(如果存在)和字段(如果不存在)排序查询集';T
我有两种型号:Python Django:如何按相关对象(如果存在)和字段(如果不存在)排序查询集';T,python,django,postgresql,Python,Django,Postgresql,我有两种型号: class Product(models.Model): name = models.CharField(max_length=200, blank=False) price = models.DecimalField(max_digits=100, decimal_places=2, blank=False) class Meta: verbose_name = 'product' verbose_name_plural
class Product(models.Model):
name = models.CharField(max_length=200, blank=False)
price = models.DecimalField(max_digits=100, decimal_places=2, blank=False)
class Meta:
verbose_name = 'product'
verbose_name_plural = 'products'
class PromotionPrice(models.Model):
product = models.ForeignKey(Product, related_name='promotion_prices', on_delete=models.CASCADE, null=False)
price = models.DecimalField(max_digits=100, decimal_places=2, blank=False)
start_date = models.DateTimeField(blank=False)
end_date = models.DateTimeField(blank=False)
class Meta:
verbose_name = 'promotion price'
verbose_name_plural = 'promotion prices'
我想要一个有效的方式,以订购所有的产品对象的价格,考虑到促销价格,如果它存在
例如,我有以下产品对象列表:
[
{
id: 1,
name: "Apple",
price: "5.00",
promotion_prices: []
},
{
id: 2,
name: "Banana",
price: "10.00",
promotion_prices: []
},
{
id: 3,
name: "Orange",
price: "15.00",
promotion_prices: [
{
product: 1,
price: "9.00",
start_date: "2021-03-01T00:00:00Z",
end_date: "2021-04-01T00:00:00Z"
}
]
}
]
我希望订购的结果是“苹果”、“橘子”、“香蕉”,因为“橘子”上面有促销价
我要处理数千个对象,因此使用sorted()进行排序需要花费很多时间。您可以计算每个产品的实际价格。为此,您可以使用子查询来计算产品是否具有促销价格,并使用合并函数返回其不具有促销价格的产品价格。因此,您将有每种产品的实际价格,您可以在订购中使用。大概是这样的:
from django.db.models.expressions import Subquery, OuterRef, F
from django.db.models.functions.datetime import Now
from django.db.models.functions.comparison import Coalesce
from django.db.models.query_utils import Q
Product.objects.annotate(
actual_price = Coalesce(
Subquery(
PromotionPrice.objects.filter(
Q(start_date__lte = Now(),end_date__gte=Now()),
product_id = OuterRef('id')
).values_list('price',flat=True)
),
F('price')
)
).order_by('actual_price')
您提到的
sorted()
需要很长时间才能返回,您还尝试了什么?你能提供这方面的详细信息吗?你用来获取此列表的查询集是什么?可能会添加一些类似于.order\u by('-promotion\u prices\u price')
非常感谢,这正是我想要的。