Django提供了一个
Func()表达式来促进在查询集中调用数据库函数:
Func()表达式是涉及数据库函数(如 COALESCE 和 LOWER )或聚合(如 SUM) 的所有表达式的基本类型。
关于如何在Django / GeoDjango ORM中使用数据库功能,有2个选项:
为了方便起见,让我们假设模型已命名MyModel
,并且子字符串存储在名为的变量中subst
:
from django.contrib.gis.db import models as gis_modelsclass MyModel(models.Model): name = models.CharField() the_geom = gis_models.PolygonField()
- 用于
Func()
直接调用该函数:
我们还将需要以下内容才能使查询正常工作:
* [聚合](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'))- 创建您自己的扩展数据库功能
Func
:
我们可以扩展
Func类以创建我们自己的数据库功能:
class Position(Func): function = 'POSITION'
并在查询中使用它:
MyModel.objects.aggregate(pos=Position('name', Value(subst)))GeoDjango附录:
在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')



