2013-11-18 2 views
0

Мы используем 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.

ответ

0

Я предлагаю альтернативный способ решения проблемы. Альтернатива значениям «вручную» для пользователя - пусть пользователь делает это сам. Как это:

1) Форма Trigger GET по событию выберите изменение

2) в этих обратных вызовов событий передать данные формы для просмотра - так же, как вы делаете с POST. Просто выполните запрос GET, а не запрос POST.

3) В связи просто передать request.GET в качестве первого параметра, чтобы сформировать вместо request.POST

4) Пусть существующая логика делают волшебство в методе формы инициализации.

5) шаблон возврата формы с правильными и действительными выборов от точки зрения

6) переключения существующей формы с новой формой.

Вот как я это сделаю. Не нужно ничего назначать. Позвольте пользователю сделать выбор, который они могут после обновления формы.

+0

Метод формы - сообщение, и мы не хотим его менять. Мы используем AJAX для обновления списков городов и/или регионов, если пользователь выбирает новую страну или регион. Но когда форма загружается после того, как пользователь отправляет, если форма не проверяется, мы не хотим использовать AJAX, мы хотим, чтобы форма загружалась с правильной страной и регионом (если пользователь выбрал город). Страна всегда правильная, но регион может быть «(Нет)», если пользователь не изменил его до выбора города. – Uri

+0

Как я вижу - у этих видов форм всегда есть выбор страны перед выбором региона и/или города. Пользователь не может даже изменить значение города на то, что не допускается предыдущим выбором страны. Но это зависит от вас, меняя вещи «волшебным образом», вместо того, чтобы сбросить значение и позволить пользователю сделать это, всегда кажется странным для пользователя. В любом случае. Я предложил простое решение, о котором я мог подумать.Если вы не «хотите» его использовать, вам придется «хотеть» работать над более сложным. Удачи. –

+0

Пользователь может выбрать страну, оставьте регион как «Нет» и выберите город. В этом случае он увидит все города в выбранной стране. После публикации формы мы хотим изменить регион в область выбранного города, также если форма не подтверждается. – Uri

Смежные вопросы