我需要顯示報價的平均值。問題是我必須計算多對多字段組合的平均值。我也必須將所有這些分頁。計算平均值時表現不佳
我已經做到了。問題是它的性能很差,我正在尋找解決方法。
這個模型看起來是這樣的:
class Offer(models.Model):
price = DecimalField(max_digits=10, decimal_places=2)
quantity = PositiveIntegerField()
product = ForeignKey(Product)
qualifiers = ManyToManyField(Qualifier)
相關的代碼來計算平均值是這樣的:
def get_average(product, qualifiers, users=None):
offers = Offer.objects.filter(product=product)
if users is not None:
offers = offers.filter(user__in=users)
for qualifier in qualifiers:
offers = offers.filter(qualifiers=qualifier)
if not offers.count():
return None
offers = offers.aggregate(
quantity_x_price_sum=Sum(F('quantity') * F('price'), output_field=FloatField()),
quantity_total=Sum('quantity')
)
# Weighted average
return offers['quantity_x_price_sum']/offers['quantity_total']
def get_averages(product, limit=20, users=None):
averages = []
colors = product.qualifiers.filter(type=1)
sizes = product.qualifiers.filter(type=2)
other = product.qualifiers.filter(type=3)
qualifiers = [colors, sizes, other]
combinations = itertools.product(*qualifiers)
for combination in combinations:
average = get_average(product, combination, users)
if average is not None:
averages.append(average)
if len(averages) == limit:
return averages
return averages
的主要問題是在itertools.product(*預選賽)。這可以產生數百個組合。 直到len(價格)==限制,它必須迭代它們中的每一個並執行查詢。
任何幫助將受到歡迎。謝謝。
第一眼看去,你正在創建一個list組合列表(itertools.product(* qualifiers))'來獲得你的組合,然後你將它傳遞給for循環。對此的改進是創建一個生成器'組合= itertools.product(*限定符)',然後您可以將組合傳遞到for循環。這將減少生成列表的開銷,然後迭代它。 –