Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将非数据库字段添加到数据库驱动的Django模型中,并通过保留其数据类型的QuerySet进行设置?_Django_Models_Annotate - Fatal编程技术网

如何将非数据库字段添加到数据库驱动的Django模型中,并通过保留其数据类型的QuerySet进行设置?

如何将非数据库字段添加到数据库驱动的Django模型中,并通过保留其数据类型的QuerySet进行设置?,django,models,annotate,Django,Models,Annotate,我有一个Django模型,其中包含各种数据库模型字段。 管理器的一个查询集通过一些注释调用检索各种聚合。其中一些注释是定制的,可以从数据库中检索浮点值。这些注释不是模型字段的一部分。 但是,当创建queryset时,这些浮点在模型中变成了整数,我猜是因为没有模型字段将它们绑定到浮点或十进制数据类型 下面是一些代码来说明我的意思: 自定义聚合类。注意:数据库将结果强制转换为浮点: class SqlCTR(aggregates.Sum): is_ordinal = True sql

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

下面是一些代码来说明我的意思:

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

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),但结果查询集将值转换为整数,结果是0。。。 (记住CTR不是一个模型字段)

如何确保注释值以正确的数据类型加载到模型中?是否可以将非数据库模型字段设置为DecimalField或FloatField,以保留该类型

任何想法都将受到高度赞赏
谢谢

Harel

根据django代码中的文档:

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

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

aggregate = SqlCTR(col, source=source, is_summary=is_summary)
应该是:

aggregate = SqlCTR(col, source=models.DecimalField(), is_summary=is_summary)

在尝试下面的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'>)  
usr=User.objects.get(username='harel') >>>camps=Campaign.objects.campaings(usr,{'ctr_ugt':0,'sort':'ctr','dir':'DESC'}) >>>对于营地中的c: ... 打印“%s::%d/%d=%d(ctr类型为%s)”%(c,c.clicks,c.impressions,c.ctr,str(类型(c.ctr))) . .. Dan计划测试::10/15135=0(ctr类型为) DTR-04-06::35/101827=0(ctr类型为) US-Advertising-ad4::1/2991=0(ctr类型为) Harels测试新营地::51/153929=0(ctr类型为) 商业团队::161/512072=0(ctr类型为) US-Marketing-ad3::1/3405=0(ctr类型为)
我将回答我自己的问题: 事实证明(很明显),通过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\u 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.

奥马尔,这似乎不起作用(尽管这很有道理,我很有希望)。下一个注释是一个shell测试场景。请注意,计算结果应为十进制,但结果为“int”(0)。我也尝试了FloatField…我似乎无法在注释中编写代码,所以我将在下面的新答案中添加它