我在Django上写代码,遇到了一个问题。我有两个模特。
class Statistic(models.Model):
campaign_id = models.CharField(max_length=255)
adgroup_id = models.CharField(max_length=255)
ad_id = models.CharField(max_length=255)
campaign_name = models.CharField(max_length=255)
adgroup_name = models.CharField(max_length=255)
ad_name = models.CharField(max_length=255)
date = models.DateField()
spend = models.DecimalField(max_digits=10, decimal_places=2, default=0.0, )
impressions = models.IntegerField(default=0)
clicks = models.IntegerField(default=0)
conversion = models.IntegerField(default=0)
class Tonic(models.Model):
tiktok_statistic = models.ForeignKey(Statistic, on_delete=models.SET_NULL, null=True, related_name='tonic_statistic')
campaign = models.ForeignKey(Campaigns, on_delete=models.CASCADE)
date = models.DateField(max_length=256)
keyword = models.CharField(max_length=255)
clicks = models.IntegerField(default=0)
revenueUsd = models.DecimalField(max_digits=9, decimal_places=2, default=0)
id_campaign = models.CharField(max_length=255)
id_adgroup = models.CharField(max_length=255)
id_ad = models.CharField(max_length=255)
还有3个相关模型。
class Cross(models.Model):
tiktok_statistic = models.ForeignKey(Statistic, on_delete=models.SET_NULL, null=True,
related_name='cross_statistic')
campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE)
date = models.DateField(max_length=256)
keyword = models.CharField(max_length=255, null=True)
clicks = models.IntegerField(default=0)
revenue = models.DecimalField(max_digits=9, decimal_places=2, default=0)
id_campaign = models.CharField(max_length=255)
id_adgroup = models.CharField(max_length=255)
id_ad = models.CharField(max_length=255)
我在Rest Framework中创建了endpoint。
class StatisticViewSet(ReadOnlyModelViewSet):
queryset = Statistic.objects.all().values('campaign_name').prefetch_related(
'tonic_statistic').annotate(
spend=Sum('spend'),
impressions=Sum('impressions'),
clicks=Sum('clicks'),
conversions=Sum('conversion'),
revenue_tonic=Sum('tonic_statistic__revenueUsd'),
revenue_cross=Sum('cross_statistic__revenue')
).order_by('-spend')
当我注解了花费,展示,点击和转换的SUM时,我得到的值是所需值的100-200倍。例如,我的支出应该是4,000,我得到了90000。我认为这是因为相关模型的价值被拉高了。
我可以设置distinct=True,然后值变得接近正确,但在这种情况下,一些数据丢失。
你能告诉我怎么修吗?也许我可以只从当前模型设置SPEND和其他字段,比如“self__spend”?
1条答案
按热度按时间ffdz8vbo1#
由于相关模型中的重复条目通过“tonic_statistic”和“cross_statistic”字段与Statistic模型连接,因此可能会计算出错误的值。
解决这个问题的一种方法是使用子查询分别计算相关模型的总和,然后将它们与主查询连接。下面是一个如何实现的示例:
在这个例子中,我们首先定义两个子查询来分别计算相关模型的“revenueUsd”和“revenue”字段的总和。我们使用“OuterRef”表达式引用主查询的“campaign_name”字段,并使用“Coalesce”函数将空值转换为零。
然后,我们使用“Subquery”表达式用这些子查询来注解主查询,并使用“annotate”函数将它们与主查询连接起来。最后,我们像之前一样计算主查询中字段的总和。
这将为字段给予正确的和,同时避免相关模型中的任何重复条目。