如何在Django ORM中无需extra将geometry转geography实现ST_DWITHIN过滤?
Django ORM替代废弃的extra()实现ST_DWITHIN地理查询
问题场景
我的Django项目中,Building模型定义了SRID为4326(WGS 84)的geometry类型字段shape,需要实现对应以下SQL的查询:
select * from building where (ST_DWITHIN(shape::geography, ST_MakePoint(1.9217,47.8814)::geography,20))
目前只能用已标记为废弃的extra()函数实现:
Building.objects.extra( where=[ f"ST_DWITHIN(shape::geography, ST_MakePoint({lng}, {lat})::geography, {radius})" ])
想知道是否可以不脱离ORM框架实现该查询,比如使用Cast函数?
解决方案
完全可以通过Django GIS提供的原生ORM工具实现,无需依赖extra(),具体实现如下:
1. 导入所需工具和函数
from django.contrib.gis.db.models.functions import Cast, ST_DWithin, ST_MakePoint from django.contrib.gis.geos import Point from django.contrib.gis.db.models import Geography
2. 构建ORM查询语句
方式一:通过Cast转换类型
lng = 1.9217 lat = 47.8814 radius = 20 buildings = Building.objects.filter( ST_DWithin( # 将geometry字段转为geography类型 Cast('shape', Geography(srid=4326)), # 构建并转换查询点为geography类型 Cast(ST_MakePoint(lng, lat), Geography(srid=4326)), radius ) )
方式二:直接使用Point对象(更简洁)
# 创建WGS84坐标系的点对象 point = Point(lng, lat, srid=4326) buildings = Building.objects.filter( ST_DWithin( Cast('shape', Geography(srid=4326)), point, radius ) )
代码说明
Cast('shape', Geography(srid=4326)):对应SQL中的shape::geography,将模型的geometry字段转换为geography类型ST_MakePoint(lng, lat)/Point对象:Django会自动将其转换为SQL中的ST_MakePoint(...)::geography语法ST_DWithin:直接映射PostGIS的ST_DWITHIN函数,用于判断两个地理对象是否在指定距离范围内
内容的提问来源于stack exchange,提问作者Istopopoki
相关产品推荐
相关产品推荐

