ich folgende Modell-Manager habe, die auf einem SalesRecord betreiben:Django - mit Anmerkungen versehen gewichteten AVG von Gruppe
def by_variety_and_date(self, start_date, end_date):
return self.model.objects.filter(
date__range=(start_date, end_date)
).values(
"variety"
).annotate(
qty_applied=Sum('qty_applied'),
margin=Avg('margin')
)
Was ich wirklich mag, ist für die margin=Avg('margin')
einen gewichteter Durchschnitt zurückzukehren, basierend auf qty_applied
. Gibt es eine Möglichkeit, dies mit Djangos Annotate/Aggregat-Abfragen zu tun? Ich experimentiere mit dem Stringing .aggregate() bis zum Ende davon, aber ich möchte immer noch den Durchschnittswert pro variety
wie von diesem Queryset beschrieben.
Das Modell in diesem Fall wie folgt aussieht:
class Sale(models.Model):
margin = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=12)
qty_applied = models.IntegerField(null=True, blank=True)
variety = models.ForeignKey(Variety, null=True)
totals = Totals()
EDIT
Dies ist, was ich schließlich mit endete. Es ist ein bisschen wackelig, aber es macht den Trick.
def by_variety_and_date(self, start_date, end_date):
return self.model.objects.filter(
date__range=(start_date, end_date)
).values(
"variety"
).annotate(
qty_applied=Sum('qty_applied'),
profit=Sum('profit'),
cogs=Sum('cogs'),
sales=Sum('value'),
margin=Sum(
(F('qty_applied')*F('margin')), output_field=FloatField()
)/Sum(
'qty_applied', output_field=FloatField())
)
habe ich die F-Objekte als @WTower jedes Objekt zu multiplizieren vorgeschlagen margin
von seinen qty_applied
, dann das Ganze in einem Sum
gewickelt und geteilt durch die Sum
der qty_applied
alle Objekte in der Gruppe. Klappt wunderbar!
Kein benutzerdefiniertes SQL benötigt :). Dies ist eine benutzerdefinierte Managermethode, übrigens. –