我有一个包含各种数据库模型字段的Django模型。 管理器的一个查询集通过一些注释调用检索各种聚合。其中一些注释是自定义的,并从数据库中检索浮点值。这些注释不是模型字段的一部分。 但是,当创建查询集时,那些浮点数在模型中变成整数,我猜是因为没有模型字段将它们绑定到浮点数或十进制数据类型。
这里有一些代码来说明我的意思:
自定义聚合类。请注意,数据库将结果转换为float:
class SqlCTR(aggregates.Sum):
is_ordinal = True
sql_function = 'SUM'
sql_template= "CASE WHEN sum(campaignmanager_adstats.impressions) > 0 THEN sum(campaignmanager_adstats.clicks)/sum(campaignmanager_adstats.impressions)::float ELSE 0::float END"
class CTR(Sum):
name='CTR'
def add_to_query(self, query, alias, col, source, is_summary):
aggregate = SqlCTR(col, source=source, is_summary=is_summary)
query.aggregates[alias] = aggregate
这是查询集:
camps = self.select_related(depth=3).\
annotate( impressions=Sum('ad__adstats__impressions'),\
clicks=Sum('ad__adstats__clicks'),\
ctr=CTR('ad__adstats__clicks'),\
exclude(**campaignExclude).\
filter(**campaignArgs).order_by(sortBy)
问题在于虽然查询本身运行正常并将CTR作为浮点数返回,但将其排序为浮点数并过滤它就好了(如果我在Postgres的控制台中运行生成的sql),生成的Queryset会将值转换为整数,导致0 ... (请记住点击率不是模型字段。)
如何确保带注释的值以正确的数据类型加载到模型中?我可以设置DecimalField或FloatField的非数据库模型字段,它将保留类型吗?
任何想法都将受到高度赞赏!
由于
Harel的
答案 0 :(得分:0)
根据django代码中的文档:
source是底层字段或聚合定义 列引用。如果聚合不是序数或 计算类型,此引用用于确定强制 输出类型的聚合。
因此,尝试将字段类型放在SqlCTR的构造函数中。
aggregate = SqlCTR(col, source=source, is_summary=is_summary)
应该是:
aggregate = SqlCTR(col, source=models.DecimalField(), is_summary=is_summary)
答案 1 :(得分:0)
这段代码在尝试下面的Omer提案之后,从django shell中输出结果......似乎无法在评论中写出任何代码......
>>> usr = User.objects.get(username='harel')
>>> camps = Campaign.objects.campaigns(usr, {'ctr__gt':0, 'sort':'ctr','dir':'DESC'})
>>> for c in camps:
... print "%s:: %d/%d=%d (ctr type is %s)" % (c, c.clicks, c.impressions, c.ctr, str(type(c.ctr)))
. ..
Dan Schedule Test:: 10/15135=0 (ctr type is <type 'int'>)
DTR-04-06:: 35/101827=0 (ctr type is <type 'int'>)
US-Advertising-ad4:: 1/2991=0 (ctr type is <type 'int'>)
Harels Test New Camp:: 51/153929=0 (ctr type is <type 'int'>)
Commercial Team:: 161/512072=0 (ctr type is <type 'int'>)
US-Marketing-ad3:: 1/3405=0 (ctr type is <type 'int'>)
答案 2 :(得分:0)
我会回答我自己的问题:
结果(显然),通过django代码本身是很有帮助的。
我的SqlCTR调用具有:is_ordinal = True
,其中django代码状态中的注释:
is_ordinal, a boolean indicating if the output of this aggregate
is an integer (e.g., a count)
虽然我需要is_computer=True
is_computed, a boolean indicating if this output of this aggregate
is a computed float (e.g., an average), regardless of the input
type.