我在django的一个区域和一家商店有2个模型,模型是这样的:
from django.contrib.gis.db import models
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D
from location_field.models.spatial import LocationField
class Zone(models.Model):
name = models.CharField(max_length=200)
location_point = LocationField(based_fields=['city'], zoom=7, default=Point(51.67, 32.65))
radius = models.IntegerField(default=1000) # radius in meters
class Shop(models.Model):
name = models.CharField(max_length=200)
location_point = LocationField(based_fields=['city'], zoom=7, default=Point(51.67, 32.65), null=True, blank=True)
zone = models.ForeignKey(Zone, on_delete=models.CASCADE, null=True)
LocationField是在Django管理员中具有更好地图的PointField。
我要在每个商店中根据商店位置,区域位置和半径自动选择区域。如果没有半径要支持车间的区域,则将为“无”。我尝试了以下查询:
zone_list = Zone.objects.filter(
location_point__distance_lte=(
shop.location_point, D(m=models.F('radius'))
)
)
但是我得到这个错误:
TypeError:float()参数必须是字符串或数字,而不是'F'
我该如何解决?
答案 0 :(得分:1)
显然以前的方法无效!
这似乎发生在MeasureBase
(继承自Distance
/D
的django.contrib.gis.measure
类内部,更具体地讲,是in the default_units
method在它尝试转换str
或float
的数字输入值,但接收到F
表达式。
我们可以作为一种解决方法,annotate
Distance
( 请谨慎使用此Distance
方法,因为它来自GeoDjango地理数据库函数< / em> )与当前shop.location_point
之间的距离,然后我们可以按距离实例location_point
的距离<=
过滤该距离:
radius
对@ e4c5的出色回答表示敬意:GeoDjango filter by distance from a model field
另一种方法是完全消除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'))
部分,然后直接进行annotation
的过滤:
Distance
您可以尝试使用 Cast()
方法将from django.contrib.gis.db.models.functions import Distance
zone_list = Zone.objects.filter(
radius_gte=Distance('location_point', shop.location_point)
)
的结果强制转换为F('radius')
,以将Integer转换为Float。
FloatField()