1

我有一个包含各种数据库模型字段的 Django 模型。经理的查询集之一通过一些注释调用检索各种聚合。其中一些注释是定制的,并从数据库中检索浮点值。这些注释不是模型字段的一部分。但是,当创建查询集时,这些浮点数在模型中变成整数,我猜是因为没有模型字段将它们绑定到浮点数或十进制数据类型。

这是一些代码来演示我的意思:

自定义聚合类。请注意,数据库将结果转换为浮点数:

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 将值转换为整数,导致0s...(记住 CTR 不是模型字段)。

我怎样才能确保带注释的值以正确的数据类型加载到模型中?我可以设置保留类型的 DecimalField 或 FloatField 的非数据库模型字段吗?

任何想法将不胜感激!
谢谢哈雷尔
_

4

3 回答 3

0

根据 django 代码中的文档:

source 是列引用的基础字段或聚合定义。如果聚合不是序数或计算类型,则此引用用于确定聚合的强制输出类型。

因此,尝试将字段类型放入 SqlCTR 的构造函数中的 source 中。

aggregate = SqlCTR(col, source=source, is_summary=is_summary)

应该:

aggregate = SqlCTR(col, source=models.DecimalField(), is_summary=is_summary)
于 2010-09-02T21:55:46.387 回答
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'>)  
于 2010-09-03T11:01:45.687 回答
0

我会回答我自己的问题:结果(显然),通过 django 代码本身是有很大帮助的。我的 SqlCTR 调用有:is_ordinal = Truedjango 代码中的注释状态:

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.
于 2010-09-06T12:15:03.713 回答