Рассчитать среднее время доставки (дни) Django ORM
Я хочу вычислить среднее время доставки (в днях) продуктов, используя ORM
одиночный запрос (Причина использования одиночного запроса в том, что у меня 10000+ записей в базе данных и я не хочу итерировать их в циклах). Вот пример файла моделей, у меня есть:
class Product(models.Model):
name = models.CharField(max_length=10)
class ProductEvents(models.Model):
class Status(models.TextChoices):
IN_TRANSIT = ("in_transit", "In Transit")
DELIVERED = ("delivered", "Delivered")
product = models.ForiegnKey(Product, on_delete=models.CASCADE)
status = models.CharField(max_length=255, choices=Status.choices)
created = models.DateTimeField(blank=True)
Для расчета времени доставки для 1 продукта это:
product = Product.objects.first()
# delivered_date - in_transit_date = days_taken
duration = product.productevent_set.get(status='delivered').created - product.productevent_set.get(status='in_transit').created
Я здесь, чтобы получить вашу помощь, чтобы начать самому работать над этим, чтобы я мог вычислить среднее время между всеми Продуктами. Я бы предпочел, чтобы это было сделано в одном запросе из-за производительности.
Базовым решением является аннотирование каждого продукта с минимальным временем создания для связанных событий, имеющих статус "в пути", и выбор максимального времени для событий со статусом "доставлено", затем аннотирование различий и агрегирование среднего значения различий
from django.db.models import Min, Max, Q, F, Avg
Product.objects.annotate(
start=Min('productevents__created', filter=Q(productevents__status=ProductEvents.Status.IN_TRANSIT)),
end=Max('productevents__created', filter=Q(productevents__status=ProductEvents.Status.DELIVERED))
).annotate(
diff=F('end') - F('start')
).aggregate(
Avg('diff')
)
Возвращает словарь, который должен выглядеть как
{'diff__avg': datetime.timedelta(days=x, seconds=x)}