开发者

Django Form doesn't accept selection as valid choice. Can't see why

开发者 https://www.devze.com 2023-02-11 06:08 出处:网络
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

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 POSTs 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)
0

精彩评论

暂无评论...
验证码 换一张
取 消