Очевидно, что предыдущий подход не работает !!
Это, кажется, происходит внутри MeasureBase
класса django.contrib.gis.measure
(который Distance
/ D
наследуется от) и, более конкретно, в методе default_units
, где он пытается преобразовать str
или числовые входные значения в float
, но вместо этого получает выражение F
.
То, что мы можем сделать в качестве обходного пути, это annotate
Distance
( осторожно с этим Distance
методом, потому что он исходит из функций GeoDjango для географической базы данных ) между shop.location_point
и текущим location_point
, и тогда мы можем отфильтровать это расстояние на <=
, чем экземпляр radius
:
from django.contrib.gis.db.models.functions import Distance
zone_list = Zone.objects.annotate(
distance=Distance('location_point', shop.location_point)
).filter(distance__lte=F('radius'))
Престижность этому превосходному ответуот @ e4c5: Фильтр GeoDjango по расстоянию от модельного поля
Другой подход заключается в том, чтобы полностью исключить часть annotation
и перейти к фильтрации по Distance
:
from django.contrib.gis.db.models.functions import Distance
zone_list = Zone.objects.filter(
radius_gte=Distance('location_point', shop.location_point)
)
Я оставляю это здесь для непрерывности комментариев: Вы можете попытаться привести результат F('radius')
как FloatField()
, используя метод Cast()
, чтобы превратить целое число в число с плавающей точкой.
zone_list = Zone.objects.filter(
location_point__distance_lte=(
shop.location_point,
D(m=Cast('radius', output_field=models.FloatField()))
)
)