Django提供了一个Func()
表达式来促进在查询集中调用数据库函数:
Func()
表达式是涉及数据库函数(如 和 )或聚合(如 的所有表达式的基本类型。
关于如何在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()
* [聚合](https://docs.djangoproject.com/en/1.11/topics/db/aggregation/)为我们数据库中的每个条目添加一个字段。
* [`F()`](https://docs.djangoproject.com/en/1.11/ref/models/expressions/#f-expressions)这允许[在模型字段之间以及模型字段之间执行算术运算。](https://stackoverflow.com/questions/45593440/how-to-execute-arithmetic-operations-between-model-fields-in-django)
* [`Value()`](https://github.com/django/django/blob/master/django/db/models/expressions.py#L620)这将净化任何给定的值([为什么这很重要?)](https://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work?answertab=Votes#tab-top)
查询:
MyModel.objects.aggregate(
pos=Func(F('name'), Value(subst), function='POSITION')
)
class Position(Func):
function = 'POSITION'
并在查询中使用它:
MyModel.objects.aggregate(pos=Position('name', Value(subst)))
在GeoDjango中,为了导入与GIS相关的功能(如PostGIS
的Transform
功能),Func()
必须将方法替换为GeoFunc()
,但实际上该方法在相同的原则下使用:
class Transform(GeoFunc):
function='ST_Transform'
如果您想创建一个自定义数据库函数(选项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')