我正在尝试查找给定邮政编码一定距离内的所有邮政编码。我通过使用定制的聚合函数计算距离,用距离注释查询集,并根据该“距离”字段过滤查询集来做到这一点。
聚合函数正确计算距离,注释在查询集中正确创建“距离”字段。但是,过滤器总是返回一个空的查询集。当我使用“邮政编码”或“状态”等其他字段进行过滤时,它工作正常,但当我使用带注释的“距离”值作为过滤器值时返回空。我究竟做错了什么?
这是自定义聚合函数:
from django.db import models
from django.db.models import Aggregate
from django.db.models.sql.aggregates import Aggregate as AggregateImpl
class DistanceFromImpl(AggregateImpl):
sql_function = ''
is_computed = True
is_ordinal = True
sql_template = ('3959 * acos( cos( radians(%(t_lat)f) ) * cos( radians( latitude ) ) * '
'cos( radians( longitude ) - radians(%(t_lon)f) ) + sin( radians(%(t_lat)f) ) * '
'sin( radians( latitude ) ) )')
def __init__(self, col, target, **extra):
self.col = col
self.target = target
self.extra = extra
def _default_alias(self):
return '%s__%s' % (str(self.target), self.__class__.__name__.lower())
default_alias = property(_default_alias)
def add_to_query(self, query, alias, col, source, is_summary):
super(DistanceFrom, self).__init__(col, source, is_summary, **self.extra)
query.aggregate_select[alias] = self
def as_sql(self, qn, connection):
"Return the aggregate, rendered as SQL."
return self.sql_template % { 't_lon': self.target.longitude,
't_lat': self.target.latitude }
class DistanceFrom(Aggregate):
name="DistanceFromImpl"
def add_to_query(self, query, alias, col, source, is_summary):
aggregate = DistanceFromImpl(col, source=source, is_summary=is_summary, **self.extra)
query.aggregates[alias] = aggregate
我从这里抓取了这个和其他代码: https ://github.com/elfsternberg/django-zipdistance/blob/master/zipdistance/models.py
我的邮政编码模型称为 ZipDistance。我可以很容易地从给定的 ZipDistance 中获得一个带有注释距离的查询集。所以这很好用:
>>> zip1 = ZipDistance.objects.get(zipcode='01234')
>>> qs = ZipDistance.objects.annotate(distance=DistanceFrom('zipcode', target=zip1))
>>> qs[1].distance
5 # Second entry in queryset is 5 miles away from zipcode '01234'
但是任何按距离过滤的结果总是空的:
>>> qs.filter(distance__lte=99999)
[]
我正在使用自己的装置来填充我的数据库(即 MySQL)。问题可能是我使用的是 Django 1.5 版,并且代码是为早期版本编写的。我只是不确定,几天来我一直在尝试我能想到的一切。