【发布时间】:2017-09-07 22:33:08
【问题描述】:
已解决:请参阅我自己的答案以获得解释。
我正在编写一个 API 来帮助我在需要时维护我的数据库。
我的 API 的一个功能是更新所有相关对象的特定 geoDjango Point 字段,这要归功于我的模型的专用方法 (这对于 EDIT 1 来说毫无用处,见下文)。
我一直面临的问题如下:在多个对象上调用该方法时,似乎没有任何内容保存到数据库中,即使在浏览对象时调用 save 方法似乎有效。
请参阅EDIT 2,我发现这个问题是 geoDjango Point 对象特有的(其他一切都按预期更新)。
下面是我的模型:
models.py
class Location(geoModels.Model):
coord_field = geoModels.PointField(blank=True, null=True)
valTest = models.CharField(max_length=100, default="tagada") # only used to understand why coord_field can't be updated properly
def update_coord_field(self):
# some stuff is being done
self.coord_field = Point(
newLong,
newLat,
srid=3857 # I am trying to update that value
)
# nothing more
newLong 和 newLat 是通过 Google Maps API 生成的。
由于 Google Maps 似乎正在使用 SRID 3857 而 GeoDjango 在创建新的 Point 时默认使用 SRID 4326,所以我想将 self.coord_field 的 SRID 强制为 SRID 3857(我一直面临着不连贯的距离演算,所以我正在尝试使用 SRID 来解决这个问题)。
现在这是我的脚本:
script.py
from MyApp import models as MyAppModels
def update_all_coord_field():
for location in MyAppModels.Location.objects.all():
print(" old SRID : ", location.coord_field.srid)
location.update_coord_field()
location.save()
print(" new SRID : ", location.coord_field.srid)
update_all_coord_field()
但是当尝试再次执行我的脚本(或者只是尝试使用我的新值属性)时,我只能观察到没有任何内容保存到数据库中(它仍然是printlocation.coord_field.srid 的旧值Locationobjects)。
我的脚本是如何执行的:
python manage.py shell
exec(script.py)
如果我调用了两次我的脚本,这里是以下回溯(只有一个对象可以理解):
exec(script.py)
old SRID : 4326
new SRID : 3857 # so apparently object has been updated...
exec(script.py)
old SRID: 4326 # ...but this line proves that the updated value has not been pushed to the database
new SRID: 3857
你知道为什么这不起作用吗?
首次编辑:@JohnMoutafis 向我指出,已经有一个函数可以更改
SRID 的 Point 对象:transform。
Location.objects.get(pk=pk).transform(3857) # define a new value of SRID
它很有用,但它并没有解决我的问题!请注意,我没有使用 transform 方法更新我的代码。
第二次编辑:我经历了很多痛苦才明白这是不是
save 方法不起作用!实际上,如果我尝试更新 MyAppModel 的“临时”数据字段,一切正常并按预期更新。真正的问题只是我的coord_field 属性无法更新,我不知道为什么。
在我的脚本中,我一方面尝试了上面解释的内容,另一方面我还尝试了以下手动更新(而不是通过我的模型的自定义方法)coord_field:
MyAppModels.Location.objects.filter(pk=pk).update(
geoCoord=Point(location.geoCoord.x, location.geoCoord.y, srid=3857),
valTest="meat"
)
因此,如果我再次执行我的脚本,我会看到 valTest 已正确更新(很好!),但 geoCoord 仍然是旧值! :-( 使用错误的 SRID 和所有内容。所以,我认为我在更新 geoDjango Point object 时确实遇到了麻烦,因此我会更新我的问题的标题!
【问题讨论】:
-
请显示不工作的确切代码。我不确定你的表现是否足以说明问题所在。
-
newLong、newLat、newSRID等从何而来?您如何验证没有任何变化? -
感谢您的回答,抱歉@Sayse 在您撰写评论时我正在编辑我的帖子!我真正想要改变的是我的观点。这就是我试图通过脚本显示的内容,以检查该值是否已有效更新。 newLong、newLat 由 GoogleMaps API 计算,但 newSRID 是手动指定的(我希望与 Gmaps 相同,即 3857,而 geoDjango 默认为 4326)。这样做的目的是找出为什么通过 django 进行的距离计算与 googlemaps 的计算不一致。
标签: python django google-maps-api-3 gis geodjango