我需要为每个用户的帐户逐一加载所有统计信息。
我使用annotate()来连接和计算其他相关模型字段,但是其中一个字段在添加时会销毁所有类型,并以某种方式在queryset的先前字段中将整数乘以10。
我有3个模型:AdvertisingAccount,Campaign,UserProfile。 我已经尝试过对所有字段进行转换,但是并没有改变图片:
我需要将整数设为整数,将小数点设为具有2个小数位的小数(在模型中设置)。
预期:
ads_direct
313
303
31.12
2165.18
但已收到:
ads_direct
3443
3333
342.320000000000
8441.80000000000
视图中的代码: (我需要计算这些字段)
accounts = user.userprofile.advertising_accounts.annotate(
clicks=Cast(Sum('campaigns__clicks', filter = Q(campaigns__userprofile = userprofile)), IntegerField()),
views=Cast(Sum('campaigns__views', filter = Q(campaigns__userprofile = userprofile)),IntegerField()),
ad_spent=Cast(Sum('campaigns__ad_spent', filter = Q(campaigns__userprofile = userprofile)),DecimalField(decimal_places=2)),
money_left = Sum('budgetings__deposited', filter = Q(budgetings__userprofile = userprofile)) - (Sum('campaigns__ad_spent', filter = Q(campaigns__userprofile = userprofile))),
)
注意
如果我注释掉money_left
,则所有注释都会计算并显示OK(小数点除外:它从12位代替2位)。
我已经尝试过了,但是并没有改变情况:
accounts = user.userprofile.advertising_accounts.annotate(
clicks=Cast(Sum('campaigns__clicks', filter = Q(campaigns__userprofile = userprofile)), IntegerField()),
views=Cast(Sum('campaigns__views', filter = Q(campaigns__userprofile = userprofile)),IntegerField()),
ad_spent=Cast(Sum('campaigns__ad_spent', filter = Q(campaigns__userprofile = userprofile)),DecimalField(decimal_places=2)),
money_left = Cast((Sum('budgetings__deposited', filter = Q(budgetings__userprofile = userprofile)) - (Sum('campaigns__ad_spent', filter = Q(campaigns__userprofile = userprofile)))),DecimalField(decimal_places=2)),
)
模板
{% for i in accounts %}
{{i.foreign_system_name}}<p></p>
{{i.clicks}}<p></p>
{{i.views}}<p></p>
{{i.ad_spent}}<p></p>
{{i.money_left}}<p></p>
<p></p>
{% endfor %}
型号:
1
from django.db import models
from payments.models import Trade
# from users.models import UserProfile
# Create your models here.
class AdvertisingAccount(models.Model):
balance = models.DecimalField(max_digits=12, decimal_places=2, default=0, blank=True, null=True)
# eg yandex_direct or google_adwords
foreign_system_name = models.CharField(max_length=30, blank=True, default=None)
foreign_system_id = models.IntegerField(default=None, blank=True, null=True)
def __str__(self):
return self.foreign_system_name + '--' + str(self.foreign_system_id)
class Campaign(models.Model):
userprofile = models.ForeignKey('users.UserProfile', on_delete=models.PROTECT, related_name='campaigns')
# needs to open access to audience
trade = models.ForeignKey('payments.Trade', on_delete=models.PROTECT, related_name='campaigns')
ad_account = models.ForeignKey('AdvertisingAccount', on_delete=models.PROTECT, related_name='campaigns')
views = models.IntegerField(default=0, blank=True, null=True)
clicks = models.IntegerField(default=0, blank=True, null=True)
ad_spent = models.DecimalField(max_digits=12, decimal_places=2, default=0, blank=True, null=True)
def __str__(self):
return str(self.userprofile) + '--' + str(self.ad_account.foreign_system_name) + '--' + str(self.trade.ad_budget)
2
class AdAccountsBudgeting(models.Model):
userprofile = models.ForeignKey(UserProfile, on_delete=models.PROTECT)
ad_account = models.ForeignKey('advertiser.AdvertisingAccount', on_delete=models.PROTECT, related_name='budgetings')
deposited = models.DecimalField(max_digits=12, decimal_places=2, default=0, blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.userprofile) + '--' + str(self.ad_account) + '--' + str(self.deposited)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.PROTECT)
role = models.CharField(max_length=15, default=None)
balance = models.DecimalField(max_digits=12, decimal_places=2, default=0, blank=True, null=True)
deposits = models.DecimalField(max_digits=12, decimal_places=2, default=0, blank=True, null=True)
advertising_accounts = models.ManyToManyField('advertiser.AdvertisingAccount', through='AdAccountsRelations', related_name='userprofiles' )
advertising_accounts_deposited = models.ManyToManyField('advertiser.AdvertisingAccount', through='AdAccountsBudgeting')
def __str__(self):
return self.user.username
注释时可能出什么毛病?我应该怎么做才能达到预期的行为?