GeoDjango中创建Store后无法修改经纬度的问题求助
问题:使用ModelForm更新地理坐标时无法修改经纬度
我定义了如下Store模型:
# models.py class Store(models.Model): title = models.CharField(max_length = 50) point = models.PointField(null = True, blank = True) deleted = models.BooleanField(default=False)
同时编写了StoreForm表单,支持将输入的纬度(latitude)和经度(longitude)转换为Point类型存入point字段:
# forms.py class StoreForm(forms.ModelForm): latitude = forms.FloatField( min_value = -90, max_value = 90, required = True, ) longitude = forms.FloatField( min_value = -180, max_value = 180, required = True, ) class Meta(object): model = Store exclude = ['deleted'] widgets = {'point': forms.HiddenInput()} def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) coordinates = self.initial.get('point', None) if isinstance(coordinates, Point): self.initial['longitude'], self.initial['latitude'] = coordinates.tuple def clean(self): data = super().clean() latitude = data.get('latitude') longitude = data.get('longitude') point = data.get('point') if latitude and longitude and not point: data['point'] = Point(longitude, latitude) return data
使用该表单创建Store时,前端可正常输入经纬度并转换为point字段存入后端,数据存储正常。但使用同一表单(传入对应实例)更新Store时,虽能显示原经纬度值,却无法修改经纬度,请问这是为什么?
注:我尝试过其他方式,但只有当前这种方式能实现经纬度转point字段,希望能得到修复方案。
原因分析
问题出在clean方法的判断条件上:if latitude and longitude and not point:。
更新场景下,point字段是HiddenInput组件,会携带原有实例的point值一起提交,导致data.get('point')不为空,后续生成新Point的代码不会执行,新输入的经纬度也就无法替换原有值。
修复方案
修改clean方法的判断逻辑,只要用户输入了有效的经纬度,就直接用新值生成Point覆盖原有值:
def clean(self): data = super().clean() latitude = data.get('latitude') longitude = data.get('longitude') # 只要经纬度参数有效,就生成新Point覆盖原有值 if latitude is not None and longitude is not None: data['point'] = Point(longitude, latitude) return data
另外可以优化__init__方法,优先从实例中读取坐标(编辑场景更可靠):
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 编辑场景优先从实例取point,初始化场景再看initial if self.instance and self.instance.point: coordinates = self.instance.point else: coordinates = self.initial.get('point', None) if isinstance(coordinates, Point): self.initial['longitude'], self.initial['latitude'] = coordinates.tuple
这样修改后,编辑时用户输入的新经纬度会正确替换原有point值,同时保留原有的经纬度转Point核心逻辑。
内容的提问来源于stack exchange,提问作者Shaheem PP
相关产品推荐
相关产品推荐

