如何在Django中创建/使用自定义数据库函数

时间:2017-10-11 13:51:06

标签: python django database geodjango

序言

这是SO中经常出现的问题:

可以应用于上述以及以下内容:

我想在SO文档上撰写一个示例,但自2017年8月8日关闭以来,我将遵循this widely upvoted and discussed meta answer的建议并将我的示例写为自我回答的帖子。

当然,我也很高兴看到任何不同的方法!!

问题:

Django / GeoDjango有一些数据库函数,如Lower()MakeValid(),可以像这样使用:

Author.objects.create(name='Margaret Smith')
author = Author.objects.annotate(name_lower=Lower('name')).get()
print(author.name_lower)

有没有办法根据现有的数据库函数使用和/或创建我自己的自定义数据库函数,如:

如何在Django / GeoDjango ORM中应用/使用这些功能?

1 个答案:

答案 0 :(得分:6)

Django提供了Func()表达式,以便于在查询集中调用数据库函数:

  

Func()表达式是涉及数据库函数的所有表达式的基本类型,如 COALESCE LOWER ,或聚合 SUM

如何在Django / GeoDjango ORM中使用数据库函数有两个选项:

为方便起见,我们假设模型名为MyModel,并且子字符串存储在名为subst的变量中:

from django.contrib.gis.db import models as gis_models

class MyModel(models.Model):
    name = models.CharField()
    the_geom = gis_models.PolygonField()
  1. 使用Func()直接调用该函数:

    我们还需要以下内容才能使查询正常工作:

    查询:

    MyModel.objects.aggregate(
        pos=Func(F('name'), Value(subst), function='POSITION')
    )
    
  2. 创建自己的数据库功能Func

    我们可以扩展Func类来创建我们自己的数据库函数:

    class Position(Func):
        function = 'POSITION'
    

    并在查询中使用它:

    MyModel.objects.aggregate(pos=Position('name', Value(subst)))
    
  3. GeoDjango附录:

    GeoDjango中,Func()方法被GeoFunc()取代,并以相同的方式使用。

    概括自定义数据库功能附录:

    如果您想要创建自定义数据库功能(选项2)并且希望能够在不事先了解任何数据库的情况下将其用于任何数据库,则可以使用Func' s {{ 1}}方法,只要你想要使用的函数存在于每个数据库中

    as_<database-name>