11👍
I think you’re going to have to drop some SQL in to do what you want, as the GeoDjango helpers don’t have a way of you making a suitable Distance
object that is simultaneously a Django F
object (ie field lookup). You don’t say which database you’re using, but here’s how you do it with PostGIS:
Order.objects.all().extra(
where=['ST_Distance(origin, ST_PointFromText(%s, 4326)) <= CAST(range AS double precision) / 1000'],
params=[user.profile.geo_location.wkt]
)
Let’s explain what’s happening here, because it’s pretty thorny. Going from the left:
.extra()
allows you to add extra fields and restrictions into a query; here we’re adding a restrictionST_Distance()
is the PostGIS function that the GeoDjangodistance_lte
operator converts into (from the Django documentation)ST_PointFromText()
converts from WKT syntax into a PostGIS Geometry object4326
is the default SRID for Django, but not for PostGIS so we have to specify it- we have to
CAST
your field to double precision because you’re using an integer - then we have to divide by 1000 to convert from metres into kilometres, which I believe is what we need
- GeoDjango
Point
fields have an accessor.wkt
which gives their WKT representation, which we needed earlier in ourST_PointFromText()
call
Note that according to the PostGIS documentation, ST_Distance()
doesn’t use indexes, so you may want to investigate using ST_DWithin()
instead (it’s documented right after ST_Distance()
).
Source:stackexchange.com