Django有这些函数,这些函数已经添加到
pull request 9622 [GitHub]
django.db.models.functions.math
模块。但不是在
django-2.1
lists the source code
.
原来这个函数是开着的
most popular database systems the same [Django ticket]
. 您可以添加
source code [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'))