【发布时间】:2013-12-01 16:46:39
【问题描述】:
我们使用 Django 1.4.3 和 django-cities-light 2.1.5 来创建我们的网站。我们正在使用表单的__init__ 方法来更新地区和城市的列表。问题是,如果用户选择了一个城市并且表单没有验证,我想将区域选择更改为所选城市的区域。代码如下:
def __init__(self, instance, *args, **kwargs):
super(ContentItemModelForm, self).__init__(*args, instance=instance, **kwargs)
....
....
....
country_id = None
if ((hasattr(self, "initial")) and ("country_id" in self.initial)):
country_id = int(self.initial['country_id']) if self.initial['country_id'] else None
elif ((hasattr(self, "data")) and (u'country_id' in self.data)):
country_id = int(self.data[u'country_id']) if self.data[u'country_id'] else None
region_id = None
if ((hasattr(self, "initial")) and ("region_id" in self.initial)):
region_id = int(self.initial['region_id']) if self.initial['region_id'] else None
elif ((hasattr(self, "data")) and (u'region_id' in self.data)):
region_id = int(self.data[u'region_id']) if self.data[u'region_id'] else None
city_id = None
if ((hasattr(self, "initial")) and ("city_id" in self.initial)):
city_id = int(self.initial['city_id']) if self.initial['city_id'] else None
elif ((hasattr(self, "data")) and (u'city_id' in self.data)):
city_id = int(self.data[u'city_id']) if self.data[u'city_id'] else None
if (city_id):
city_obj = City.objects.get(geoname_id=city_id)
country_id = city_obj.country_id
region_id = city_obj.region_id
# Set current values of country_id and region_id - commented (not working).
#self.fields['country_id'].initial = country_id
#self.fields['region_id'].initial = region_id
self.fields['region_id'].choices = [("", "(None)", ),]+[(obj.id, obj.name) for obj in Region.objects.filter(country_id=country_id).order_by("name")]
if (region_id):
self.fields['city_id'].choices = [("", "(None)", ),]+[(obj.geoname_id, obj.name) for obj in City.objects.filter(country_id=country_id, region_id=region_id).order_by("name")]
else:
self.fields['city_id'].choices = [("", "(None)", ),]+[(obj.geoname_id, obj.name) for obj in City.objects.filter(country_id=country_id).order_by("name")]
检查city_id、region_id和country_id当前值的代码太长,我没有找到缩短它的方法。如果没有注释,注释行(self.fields['country_id'].initial = country_id 和self.fields['region_id'].initial = region_id)将不起作用 - 如果仅选择国家和城市,则所选区域为“(无)”(如果表单未验证)。如果表单验证,则我们根据所选城市分配 country_id 和 region_id 值(国家和地区不保存到数据库中)。
这里是城市验证:
def clean_city_id(self):
cleaned_data = self.cleaned_data
country_id = cleaned_data['country_id'] if (cleaned_data.has_key('country_id')) else None
region_id = cleaned_data['region_id'] if (cleaned_data.has_key('region_id')) else None
city_id = cleaned_data['city_id'] if (cleaned_data.has_key('city_id')) else None
if (not(city_id)):
if (region_id):
error_message = "If you select a country and a state/region, you must select a city."
self._errors["city_id"] = self.error_class([error_message])
raise forms.ValidationError(error_message)
elif (country_id):
error_message = "If you select a country, you must select a city."
self._errors["city_id"] = self.error_class([error_message])
raise forms.ValidationError(error_message)
return city_id
您知道我们如何为国家和地区分配正确的值吗?
(编辑):我们希望在选择城市后的 HTML 中的正确区域中包含 selected="selected",而不是在第一个“(无)”区域中(如果用户没有选择区域) .我们使用 AJAX 在用户选择新的国家或地区后更新列表,但我们不想在加载表单后立即使用 AJAX。
谢谢, 乌里。
【问题讨论】:
标签: django django-forms