Мы используем Django 1.4.3 с django-cities-light 2.1.5 для создания нашего сайта. Мы используем метод формы __init__
для обновления списков регионов и городов. Проблема в том, что если пользователь выбрал город и форма не подтверждается, я хочу изменить выбор региона в регионе выбранного города. Вот код:Как изменить значение формы в Django?
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
Вы знаете, как мы относим правильные значения для страны и региона?
(Изменить): Мы хотим иметь selected="selected"
в HTML правильном регионе после того, как город выбран, а не в первом «(None)» регионе (также если пользователь не выбрал регион). Мы используем AJAX для обновления списков после того, как пользователь выбирает новую страну или регион, но мы не хотим использовать AJAX сразу после загрузки формы.
Thanks, Uri.
Метод формы - сообщение, и мы не хотим его менять. Мы используем AJAX для обновления списков городов и/или регионов, если пользователь выбирает новую страну или регион. Но когда форма загружается после того, как пользователь отправляет, если форма не проверяется, мы не хотим использовать AJAX, мы хотим, чтобы форма загружалась с правильной страной и регионом (если пользователь выбрал город). Страна всегда правильная, но регион может быть «(Нет)», если пользователь не изменил его до выбора города. – Uri
Как я вижу - у этих видов форм всегда есть выбор страны перед выбором региона и/или города. Пользователь не может даже изменить значение города на то, что не допускается предыдущим выбором страны. Но это зависит от вас, меняя вещи «волшебным образом», вместо того, чтобы сбросить значение и позволить пользователю сделать это, всегда кажется странным для пользователя. В любом случае. Я предложил простое решение, о котором я мог подумать.Если вы не «хотите» его использовать, вам придется «хотеть» работать над более сложным. Удачи. –
Пользователь может выбрать страну, оставьте регион как «Нет» и выберите город. В этом случае он увидит все города в выбранной стране. После публикации формы мы хотим изменить регион в область выбранного города, также если форма не подтверждается. – Uri