Django Form doesn't accept selection as valid choice. Can't see why
i made a little form where I ask the user for some location (1st stage), then geocode the location and ask the user to confirm the location (2nd stage). Everything works fine, however, when I select a choice and try to submit the form to get to the 3rd stage, the form doesn't accept the selection and issues an error "Select a valid choice". Why?
I can't see where I made a mistake. Please let me know what i did wrong. Thank you!
my forms.py
from django.http import HttpResponseRedirect
from django.contrib.formtools.wizard import FormWizard
from django import forms
from django.forms.widgets import RadioSelect
from geoCode import getLocation
class reMapStart(forms.Form):
location = forms.CharField()
CHOICES = [(x, x) for x in ("cars", "bikes")]
technology = forms.ChoiceField(choices=CHOICES)
class reMapLocationConfirmation(forms.Form):
CHOICES = []
locations = forms.ChoiceField(widget=RadioSelect(), choices = [])
class reMapData(forms.Form):
capacity = forms.IntegerField()
class reMapWizard(FormWizard):
def render_template(self, request, form, previous_fields, step, context=None):
if step == 1:
location = request.POST.get('0-location')
address, lat, lng, country = getLocation(location)
form.fields['locations'].choices = [(x, x) for x in address]
return super(reMapWizard, self).render_template(request, form, previous_fields, step, context)
def done(self, request, form_list):
# Send an email or save to the database, or whatever you want with
# form parameters in form_list
return HttpResponseRedirect('/contact/thanks/')
my urls.py
...
(r'^reMap/$', reMapWizard([reMapStart, reMapLocationConfirmation, reMapData])),
...
generated html code by Django for a random location after the 1st submission
<form action='.' method='POST'><div style='display:none'>
<input type='hidden' name='csrfmiddlewaretoken' value='0f61c17790aa7ecc782dbfe7438031a8' /></div>
<table>
<input type="hidden" name="wizard_step" value="1" />
<input type="hidden" name="0-location" value="market street san francisco" id="id_0-location" /><input type="hidden" name="0-technology" value="car" id="id_0-technology" /><input type="hidden" name="hash_0" value="8a654e29d73f2c2f6660b5beb182f0c8" />
<tr><th><label for="id_1-locations_0">Locations:</label></th><td><ul class="errorlist"><li>Select a valid cho开发者_Python百科ice. Market St, San Francisco, CA, USA is not one of the available choices.</li></ul><ul>
<li><label for="id_1-locations_0"><input checked="checked" type="radio" id="id_1-locations_0" value="Market St, San Francisco, CA, USA" name="1-locations" /> Market St, San Francisco, CA, USA</label></li>
</ul></td></tr>
</table>
<p><input type="submit" value="Submit" /></p>
</form>
Try setting the default choices to all of your locations or don't make it a ChoiceField
but a CharField
and set it as a ChoiceField
only where you override the form.
locations = forms.ChoiceField(widget=RadioSelect(), choices = [..all..])
I'm guessing the choices don't persist across multiple POST
s and the wizard validates all forms at the end.
Even if your form is valid for that one step, it becomes invalid at the end.
So, add all locations to the original field constructor or make it a CharField to remove auto validation of choices.
Solution after Yuji's help:
initializing the class with a CharField
class reMapLocationConfirmation(forms.Form):
locations = forms.CharField()
and then later overwriting to a choicefield
class reMapWizard(FormWizard):
def render_template(self, request, form, previous_fields, step, context=None):
if step == 1:
location = request.POST.get('0-location')
address, lat, lng, country = getLocation(location)
form.fields['locations'] = forms.ChoiceField(widget=RadioSelect(), choices = [])
form.fields['locations'].choices = [(x, x) for x in address]
return super(reMapWizard, self).render_template(request, form, previous_fields, step, context)
精彩评论