Аннотирование 2 разных моделей в Django в calcualte коэффициент конверсии - PullRequest
0 голосов
/ 27 июня 2019

У меня есть 2 модели: просмотр страницы и транзакция, моя цель - рассчитать коэффициент конверсии по этой формуле = (общая транзакция / общее количество просмотров) * 100%.

Это структура моей модели.

    class Transaction(models.Model):
        user = models.ForeignKey("User", on_delete=models.CASCADE)
        organization = models.ForeignKey(
            "Organization", on_delete=models.CASCADE, null=True
        )
        transaction_id = models.CharField(max_length=64, null=True, blank=True)
        datetime = models.DateTimeField(null=True)
        products = models.ManyToManyField("Product")
        . . . 
    class PageView(models.Model):
        user = models.ForeignKey("User", on_delete=models.CASCADE)
        organization = models.ForeignKey(
            "Organization", on_delete=models.CASCADE, null=True
        )
        datetime = models.DateTimeField(null=True)
        url = models.CharField(max_length=2048, blank=True)
        page_name = models.ForeignKey(
            "PageName", on_delete=models.SET_NULL, null=True, blank=True
        )

        products = models.ManyToManyField("Product", blank=True)
        . . .

Я пытался использовать некоторые из этого метода:

User.objects.filter(pageview__datetime__range=(startdate,enddate)).annotate(
y=ExtractYear('pageview__datetime'),
m=ExtractMonth('pageview__datetime'),
d=ExtractDay('pageview__datetime')).values(
'y', 'm', 'd').order_by(
'y', 'm', 'd').annotate(
total=(Cast(Count('conversion__id'), FloatField()) /
Cast(Count('pageview__id'), FloatField())) * 100,
pv=Count('pageview__id', distinct=True),
cv=Count('conversion__id', distinct=True))

результат равен

. . . 
{
    "y": 2019,
    "m": 4,
    "d": 3,
    "total": 87.9093198992443,
    "pv": 397,
    "cv": 349
}
. . .

проблема в том, что общее количество транзакций, когда я проверяю, используя этот запрос, отличается

Transaction.objects.filter(
pageview__datetime__range=(startdate,enddate)).annotate(
y=ExtractYear('pageview__datetime'),
m=ExtractMonth('pageview__datetime'),
d=ExtractDay('pageview__datetime')).values(
'y', 'm', 'd').order_by(
'y', 'm', 'd').annotate(cv=Count('id'))

результат:

. . . 
{
    "y": 2019,
    "m": 4,
    "d": 3,
    "cv": 99
}
. . .

просмотр страницы корректен, но транзакция неи мой расчет конверсии стал неправильным.общая сумма транзакции на тот момент должна быть 99, но я получил 349. Есть идеи?Большое спасибо.

ОБНОВЛЕНИЕ

Это мое текущее решение, во-первых, я аннотирую и просмотр страницы и транзакцию, чтобы получить список словаря.

total_pageview = PageView.objects.filter(organization=org, datetime__range=(start, end)).annotate(y=ExtractYear(
                'datetime'),m=ExtractMonth('datetime'), d=ExtractDay('datetime')).values('y', 'm', 'd').order_by('y', 'm', 'd').annotate(p=Count('id'))
total_transaction = Transaction.objects.filter(organization=org, datetime__range=(start, end)).annotate(y=ExtractYear(
                'datetime'),m=ExtractMonth('datetime'), d=ExtractDay('datetime')).values('y', 'm', 'd').order_by('y', 'm', 'd').annotate(c=Count('id'))

и затем использование цикла for для генерации json

value = []
for p in total_pageview:
    for c in total_conversion:
        if p['y'] == c['y'] and p['m'] == c['m'] and p['d'] == c['d']:
            value.append({'year':p['y'], 'month':p['m'], 'day':p['d'], 'total':(float(c['c'])/float(p['p']))*100})

Я знаю, что это очень уродливое решение, в то же время я все еще пытаюсь использовать полностью Django ORM, чтобы сделать это, любая идеябуду очень признателен, спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...