繁体   English   中英

在 Django 中使用字段值的对数注释查询集

[英]Annotate Queryset with logarithm of field value in Django

我研究了可用的 django 聚合函数,并注意到那里缺少对数。 所以,我的问题是:如何在注释查询集时使用对数? 我不能把对数查询集的评估之后,因为我需要注释不准确地与对数,而是用表达含有它,例如用于某些机型UserTask我需要注释UserF('task__cost') / Log('task__solved_count')

UPD:如果我能在不使用特定于数据库的函数(对于 Postgres)的情况下做到这一点,那就太好了,但该解决方案也是可能的。

Django 有这些功能,这些功能已添加到pull request 9622 [GitHub] 中 在开发分支中,这些已经存在于django.db.models.functions.math模块下。 但不在版本中。 Django 开发文档中提供了一个页面,其中列出了源代码

事实证明,这个函数在大多数流行的数据库系统上都是一样的 [Django ticket] 您可以添加源代码 [GitHub]

 from django.db.models import ( DecimalField, FloatField, Func, IntegerField, Transform, ) from django.db.models.functions import Cast # ... class DecimalInputMixin: def as_postgresql(self, compiler, connection, **extra_context): # Cast FloatField to DecimalField as PostgreSQL doesn't support the # following function signatures: # - LOG(double, double) # - MOD(double, double) output_field = DecimalField(decimal_places=sys.float_info.dig, max_digits=1000) clone = self.copy() clone.set_source_expressions([ Cast(expression, output_field) if isinstance(expression.output_field, FloatField) else expression for expression in self.get_source_expressions() ]) return clone.as_sql(compiler, connection, **extra_context) class OutputFieldMixin: def _resolve_output_field(self): has_decimals = any(isinstance(s.output_field, DecimalField) for s in self.get_source_expressions()) return DecimalField() if has_decimals else FloatField() # ... class Log(DecimalInputMixin, OutputFieldMixin, Func): function = 'LOG' arity = 2 def as_sqlite(self, compiler, connection, **extra_context): if not getattr(connection.ops, 'spatialite', False): return self.as_sql(compiler, connection) # This function is usually Log(b, x) returning the logarithm of x to # the base b, but on SpatiaLite it's Log(x, b). clone = self.copy() clone.set_source_expressions(self.get_source_expressions()[::-1]) return clone.as_sql(compiler, connection, **extra_context)

然后导入您定义的Log函数,并像这样使用它:

User.objects.annotate(cost_solve_ratio=F('task__cost') / Log('task__solved_count'))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM