Django 提供了Func()
表达式来方便在查询集中调用数据库函数:
Func()
表达式是涉及数据库函数(如COALESCE和LOWER)或聚合(如SUM )的所有表达式的基本类型。
关于如何在 Django/GeoDjango ORM 中使用数据库函数有 2 个选项:
为方便起见,让我们假设模型已命名MyModel
,并且子字符串存储在名为 的变量中subst
:
from django.contrib.gis.db import models as gis_models
class MyModel(models.Model):
name = models.CharField()
the_geom = gis_models.PolygonField()
用于Func()
直接调用函数:
我们还需要以下内容才能使我们的查询正常工作:
查询:
MyModel.objects.aggregate(
pos=Func(F('name'), Value(subst), function='POSITION')
)
创建您自己的数据库函数扩展Func
:
我们可以扩展Func
类来创建我们自己的数据库函数:
class Position(Func):
function = 'POSITION'
并在查询中使用它:
MyModel.objects.aggregate(pos=Position('name', Value(subst)))
GeoDjango 附录:
在GeoDjango中,为了导入与 GIS 相关的函数(如PostGIS
'sTransform
函数),该Func()
方法必须替换为GeoFunc()
,但它本质上是在相同的原则下使用的:
class Transform(GeoFunc):
function='ST_Transform'
有更复杂的GeoFunc
使用案例,这里出现了一个有趣的用例:如何在 Django 中计算 Frechet 距离?
泛化自定义数据库功能附录:
如果您想创建自定义数据库函数(选项 2),并且希望能够在事先不知道的情况下将其与任何数据库一起使用,则可以使用Func
'as_<database-name>
方法,前提是您要使用的函数存在于每个数据库:
class Position(Func):
function = 'POSITION' # MySQL method
def as_sqlite(self, compiler, connection):
#SQLite method
return self.as_sql(compiler, connection, function='INSTR')
def as_postgresql(self, compiler, connection):
# PostgreSQL method
return self.as_sql(compiler, connection, function='STRPOS')