python - Django过滤位置距离与动态半径
问题描述
我在 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是一个 PointField,在 django admin 中有更好的地图。
我希望每个商店都根据商店位置、区域位置和半径自动保存选择区域。如果没有半径区域支持商店,它将是无。我试过这个查询:
zone_list = Zone.objects.filter(
location_point__distance_lte=(
shop.location_point, D(m=models.F('radius'))
)
)
但我得到这个错误:
TypeError: float() 参数必须是字符串或数字,而不是“F”
我怎样才能解决这个问题?
解决方案
这似乎发生在(/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 filter by distance from a model field
另一种方法是annotation
完全消除该部分并直接通过以下方式进行过滤Distance
:
from django.contrib.gis.db.models.functions import Distance
zone_list = Zone.objects.filter(
radius_gte=Distance('location_point', shop.location_point)
)
我将其留在这里以保持评论的连续性:
您可以尝试使用将 Integer 转换为 Float 的方法将F('radius')
结果转换为a。FloatField()
Cast()
zone_list = Zone.objects.filter(
location_point__distance_lte=(
shop.location_point,
D(m=Cast('radius', output_field=models.FloatField()))
)
)
推荐阅读
- python - pd.to_datetime() 与西班牙语言环境系统
- python - 为什么 Web3.py 交易功能不起作用?
- c# - 如何通过 IIS 使用打印机
- python - 如何在 Python 中使用 GUI Tkinter 以特定格式显示来自数据库 sqlite3 的信息?
- php - GitLab CI/CD - 学说/dbal 和 laminas/laminas-code PHP 版本问题
- authorize.net - 为 Dotnet Core 授权.Net SDK
- python - How to create this type of relationship using Django Models
- javascript - Use promised getter in VueRouter beforeEach
- r - 如何从 R 中列出的模型中提取参数?
- c# - Amazon.Lambda.Serialization.Json.JsonSerializer 是否尊重 JsonIgnore