Django сложный запрос с отношениями ForeignKey
Я использую Django 3.1.4 и у меня есть такие модели:
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils.timezone import now
class CrowdfundingOffering(models.Model):
class PlatformChoices(models.TextChoices):
buytheblock = "buytheblock", _("buytheblock")
flashfunders = "flashfunders", _("flashfunders")
mainvest = "mainvest", _("mainvest")
netcapital = "netcapital", _("netcapital")
republicco = "republicco", _("republicco")
seedinvest = "seedinvest", _("seedinvest")
smallchange = "smallchange", _("smallchange")
startengine = "startengine", _("startengine")
trucrowd = "trucrowd", _("trucrowd")
wefunder = "wefunder", _("wefunder")
platform = models.CharField(
max_length=255,
choices=PlatformChoices.choices,
)
company_name = models.CharField(max_length=255)
description = models.TextField(max_length=3000)
url = models.URLField()
funding_goal = models.FloatField(default=0)
start_date = models.DateField()
end_date = models.DateField()
class Investment(models.Model):
offering = models.ForeignKey(
CrowdfundingOffering, on_delete=models.CASCADE, related_name="investments"
)
timestamp = models.DateTimeField(default=now)
number_of_investors = models.PositiveIntegerField(default=0)
amount_invested = models.FloatField(default=0)
Заявление о проблеме
Нам нужно сделать наши данные доступными для нашей команды специалистов по анализу данных. Пока что давайте дадим им что-то базовое. Простая таблица, подобная этой, будет делать:
Platform Name | Number of offerings | Amount raised total | Success ratio |
---|---|---|---|
startengine | 34 | 60093134 | 0.45 |
wefunder | 56 | 3246765 | 0.4 |
Мы можем создать такую таблицу из нашей базы данных и сохранить ее в виде CSV-файла. Вам необходимо реализовать функцию, которая запрашивает нашу базу данных и выводит данные, показанные в таблице выше.
Количество предложений - это просто количество записей в таблице CrowdfundingOffering на каждое уникальное значение в поле платформы. Для каждой платформы можно вычислить общую сумму собранных средств, суммируя текущую сумму собранных средств каждого предложения, связанного с этой платформой (текущая собранная сумма - это последний элемент в соответствующем внешнем ключе Investment предложения). Затем вы можете рассчитать коэффициент успеха, т.е. соотношение предложений данной платформы, которые достигли или превысили свою цель финансирования.
Мое неправильное решение
# django imports
from django.db.models import Count, Sum, F, Q
# local imports
from .models import CrowdfundingOffering, Investment
def generate_csv():
result = (CrowdfundingOffering.objects
.values('platform')
.annotate(number_of_offerings=Count('platform'),
amount_raised_total=Sum('investments__amount_invested'),
# success_ratio= Count(investments__amount_invested' >='funding_goal') / Count('platform')
success_ratio=Count('platform', filter=Q(investments__amount_invested__gte=F('funding_goal'))) / Count('platform') )
.order_by()
)
print(result)
Может ли кто-нибудь помочь мне решить эту проблему (без части экспорта в CSV)?
Первая проблема, которую я не могу решить, заключается в следующем:
Похоже, что если я выполню следующий запрос, у меня будет правильное количество предложений (второй столбец в запрашиваемой таблице):
CrowdfundingOffering.objects.values('platform').annotate(Count('platform'))
Но если я выполню следующий запрос (добавлен только один метод агрегации с одним ForeignKey), то результат "Count('platform')" изменится:
CrowdfundingOffering.objects.values('platform').annotate(Count('platform'), Sum('investments__amount_invested'))