深入Django自定义查询表达式:超越Q与F对象
学习如何编写数据库引擎级别的自定义查询表达式,实现跨数据库函数的统一调用,例如自定义JSON路径提取或地理位置距离计算。 · 难度:入门 · +10XP
自定义查询表达式原理
Django ORM的Q和F对象无法覆盖所有数据库原生函数。本教程从SQL函数注册开始,通过继承Func类并重写as_sql、as_postgresql等方法,构建一个在PostgreSQL中计算两点经纬度距离的GeoDistance表达式,并使其在filter/annotate中无缝使用。你将掌握数据库后端适配模板与安全的参数注入方式。
from django.db.models import Func, FloatField
class GeoDistance(Func):
function = 'ST_DistanceSphere'
output_field = FloatField()
def as_sql(self, compiler, connection):
if connection.vendor == 'postgresql':
return super().as_sql(compiler, connection)
else:
raise NotImplementedError('Unsupported database')
# 使用:User.objects.annotate(d=GeoDistance('location', point)).filter(d__lt=1000)